bzoj2229: [Zjoi2011]最小割(分治最小割+最小割树思想)
2229: [Zjoi2011]最小割
题目:传送门
题解:
一道非常好的题目啊!!!
蒟蒻的想法:暴力枚举点对跑最小割记录...绝对爆炸啊....
开始怀疑是不是题目骗人...难道根本不用网络流???一看路牌....分治最小割?最小割树?
然后开始各种%论文...
简单来说吧,根据各种本蒟蒻不会证明的理论,那么:所有最小割都不是完全独立的,总共有n-1种(也就是树上的n-1条边)最小割 恰好和树的定义一样啊!
那么用一个solve递归函数来解决,一开始任意找两个点作为st和ed来最小割,然后分治,在分开的两个集合中继续递归,用数组记录答案
以上都是根据边所进行的离线操作,然后输入Q个询问,直接在线输出答案就ok
代码:
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<algorithm>
using namespace std;
const int inf=;
struct node
{
int x,y,c,next,other;
}a[];int len,last[];
int st,ed,n,m,T,ans;
void ins(int x,int y,int c)
{
int k1,k2;
k1=++len;
a[len].x=x;a[len].y=y;a[len].c=c;
a[len].next=last[x];last[x]=len; k2=++len;
a[len].x=y;a[len].y=x;a[len].c=c;
a[len].next=last[y];last[y]=len; a[k1].other=k2;
a[k2].other=k1;
}
int list[],h[],head,tail;
bool bt_h()
{
memset(h,,sizeof(h));h[st]=;
list[]=st;head=;tail=;
while(head!=tail)
{
int x=list[head];
for(int k=last[x];k;k=a[k].next)
{
int y=a[k].y;
if(h[y]== && a[k].c)
{
h[y]=h[x]+;
list[tail++]=y;
}
}
head++;
}
if(h[ed])return true;
return false;
}
int find_flow(int x,int flow)
{
if(x==ed)return flow;
int s=,t;
for(int k=last[x];k;k=a[k].next)
{
int y=a[k].y;
if(h[y]==h[x]+ && a[k].c && s<flow)
{
s+=t=find_flow(y,min(a[k].c,flow-s));
a[k].c-=t;a[a[k].other].c+=t;
}
}
if(s==)h[x]=;
return s;
}
int d[],num[],sta[],anss[][];
void re_num(int x)
{
num[x]=;
for(int k=last[x];k;k=a[k].next)
{
int y=a[k].y;
if(a[k].c && !num[y])
re_num(y);
}
}
void solve(int l,int r)
{
if(l==r)return ;
for(int i=;i<=len;i+=)a[i].c=a[i+].c=(a[i].c+a[i+].c)>>;//将边权重置
st=d[l];ed=d[r];ans=;
while(bt_h())ans+=find_flow(st,inf);
memset(num,,sizeof(num));
re_num(st);
for(int i=;i<=n;i++)
if(num[i])
for(int j=;j<=n;j++)
if(!num[j])
anss[i][j]=anss[j][i]=min(anss[i][j],ans);
int L=l,R=r;
for(int i=l;i<=r;i++)
{
if(num[d[i]])sta[L++]=d[i];
else sta[R--]=d[i];
}
for(int i=l;i<=r;i++)d[i]=sta[i];
solve(l,L-);solve(R+,r);//分治,递归
}
int main()
{
scanf("%d",&T);
while(T--)
{
scanf("%d%d",&n,&m);
len=;memset(last,,sizeof(last));int x,y,c;
for(int i=;i<=m;i++)scanf("%d%d%d",&x,&y,&c),ins(x,y,c);
for(int i=;i<=n;i++)d[i]=i;memset(anss,,sizeof(anss));
solve(,n);
int Q;scanf("%d",&Q);
while(Q--)
{
scanf("%d",&x);int cnt=;
for(int i=;i<=n;i++)
for(int j=i+;j<=n;j++)
if(anss[i][j]<=x)
cnt++;
printf("%d\n",cnt);
}
printf("\n");
}
return ;
}
bzoj2229: [Zjoi2011]最小割(分治最小割+最小割树思想)的更多相关文章
- 【bzoj2229】[Zjoi2011]最小割 分治+网络流最小割
题目描述 小白在图论课上学到了一个新的概念——最小割,下课后小白在笔记本上写下了如下这段话: “对于一个图,某个对图中结点的划分将图中所有结点分成两个部分,如果结点s,t不在同一个部分中,则称这个划分 ...
- [bzoj2229][Zjoi2011]最小割_网络流_最小割树
最小割 bzoj-2229 Zjoi-2011 题目大意:题目链接. 注释:略. 想法: 在这里给出最小割树的定义. 最小割树啊,就是这样一棵树.一个图的最小割树满足这棵树上任意两点之间的最小值就是原 ...
- 【BZOJ2229】[ZJOI2011]最小割(网络流,最小割树)
[BZOJ2229][ZJOI2011]最小割(网络流,最小割树) 题面 BZOJ 洛谷 题解 戳这里 那么实现过程就是任选两点跑最小割更新答案,然后把点集划分为和\(S\)联通以及与\(T\)联通. ...
- [ZJOI2011]最小割 & [CQOI2016]不同的最小割 分治求最小割
题面: [ZJOI2011]最小割 [CQOI2016]不同的最小割 题解: 其实这两道是同一道题.... 最小割是用的dinic,不同的最小割是用的isap 其实都是分治求最小割 简单讲讲思路吧 就 ...
- 最小割分治(最小割树):BZOJ2229 && BZOJ4519
定理:n个点的无向图的最小割最多n-1个. 可能从某种形式上形成了一棵树,不是很清楚. 最小割分治:先任选两个点求一边最小割,然后将两边分别递归,就能找到所有的最小割. 这两个题是一样的,直接搬din ...
- ZJOI 最小割 CQOI 不同的最小割 (最小割分治)
题目1 ZJOI 最小割 题目大意: 求一个无向带权图两点间的最小割,询问小于等于c的点对有多少. 算法讨论: 最小割 分治 代码: #include <cstdlib> #include ...
- 【LuoguP3329&4123】[ZJOI2011]最小割&[CQOI2016]不同的最小割
链接1 链接2 题意简述 第一个题 : 问图中有多少不同的最小割数值 第二个题 : \(q\) 次询问图中多少对点对之间的最小割小于 \(x\) . Sol 两个都是模板题就放一起了. 求完最小割树直 ...
- hiho 第116周,最大流最小割定理,求最小割集S,T
小Hi:在上一周的Hiho一下中我们初步讲解了网络流的概念以及常规解法,小Ho你还记得内容么? 小Ho:我记得!网络流就是给定了一张图G=(V,E),以及源点s和汇点t.每一条边e(u,v)具有容量c ...
- hdu1569 方格取数(2) 最大点权独立集=总权和-最小点权覆盖集 (最小点权覆盖集=最小割=最大流)
/** 转自:http://blog.csdn.net/u011498819/article/details/20772147 题目:hdu1569 方格取数(2) 链接:https://vjudge ...
随机推荐
- virtual table(有180个评论)
To implement virtual functions, C++ uses a special form of late binding known as the virtual table. ...
- Adding Kentico controls to the Visual Studio toolbox
https://docs.kentico.com/k10/references/kentico-controls https://docs.kentico.com/k10/references/ken ...
- tp中使用事务
是什么 事务是为了防止,多个操作,其中有失败,数据有部分被执行成功的时候使用的. 比如,银行,用户转账.张三钱扣了,结果李四钱还增加! 这个时候需要使用事务,确保张三钱扣了,李四的钱也增加,才真正的成 ...
- 随机森林算法demo python spark
关键参数 最重要的,常常需要调试以提高算法效果的有两个参数:numTrees,maxDepth. numTrees(决策树的个数):增加决策树的个数会降低预测结果的方差,这样在测试时会有更高的accu ...
- poj--3630--Phone List(字典树+前缀判断)
Phone List Time Limit: 1000MS Memory Limit: 65536KB 64bit IO Format: %I64d & %I64u Submit St ...
- 17.QT键盘
mainwindow.h #ifndef MAINWINDOW_H #define MAINWINDOW_H #include <QMainWindow> 5 #include <Q ...
- BZOJ 3729 splay维护DFS序+博弈论
思路: 这像是 阶梯Nim之类的东西 我们 直接把sg函数 设成mod(L+1)的 一棵子树 向下的奇数层上的石子xor起来 就是答案 有加点和改值的操作 就splay维护一下 //By Sirius ...
- nginx高级-前端必会
需要设置的几个参数: 基本配置文件 user www www; worker_processes auto; error_log /www/wwwlogs/nginx_error.log crit; ...
- 算法 之 aabb
题目描述:输出所有形如aabb的4位完全平方数(即前两位数字相等,后两位数字也相等). 分支和循环结合在一起时功能强大: 下面列举所有可能的结果aabb,然后判断它们是否为完全平方数.注意a的范围是1 ...
- Sphinx在windows下安装使用[支持中文全文检索]
原文地址:http://www.fuchaoqun.com/2008/11/sphinx-on-windows-xp/ 前 一阵子尝试使用了一下Sphinx,一个能够被各种语言(PHP/Python/ ...