最小割分治(最小割树):BZOJ2229 && BZOJ4519
定理:n个点的无向图的最小割最多n-1个。
可能从某种形式上形成了一棵树,不是很清楚。
最小割分治:先任选两个点求一边最小割,然后将两边分别递归,就能找到所有的最小割。
这两个题是一样的,直接搬dinic模板即可。
BZOJ2229:
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
#define mem(a,k) memset(a,k,sizeof(a))
#define rep(i,l,r) for (int i=l; i<=r; i++)
#define For(i,x) for (int i=h[x],k; i; i=e[i].nxt)
using namespace std; const int N=,inf=;
int m,n,u,v,w,x,S,T,TT,Q,tot,cnt,tmp[N],a[N],b[N],d[N],q[N*],h[N],ans[N][N];
struct E{ int to,nxt,v; }e[];
bool mark[N]; void add(int u,int v,int w){
e[++cnt]=(E){v,h[u],w}; h[u]=cnt;
e[++cnt]=(E){u,h[v],w}; h[v]=cnt;
} bool bfs(){
mem(d,); q[]=S; d[S]=;
for (int st=,ed=; st!=ed; ){
int x=q[++st];
For(i,x) if (e[i].v && !d[k=e[i].to])
d[k]=d[x]+,q[++ed]=k;
}
return d[T];
} int dfs(int x,int lim){
if (x==T) return lim;
int t,c=;
For(i,x) if (d[k=e[i].to]==d[x]+){
t=dfs(k,min(lim-c,e[i].v));
e[i].v-=t; e[i^].v+=t; c+=t;
if (c==lim) return lim;
}
if (!c) d[x]=-; return c;
} int dinic(){ int ans=; while(bfs()) ans+=dfs(S,inf); return ans; } void get(int x){
mark[x]=; For(i,x) if (!mark[k=e[i].to] && e[i].v) get(k);
} void solve(int l,int r){
if (l==r) return;
S=a[l]; T=a[r]; int t=dinic();
mem(mark,); get(S); int p=l,p0;
rep(i,,n) if (mark[i]) rep(j,,n) if (!mark[j]) ans[i][j]=ans[j][i]=min(ans[i][j],t);
for (int i=; i<=cnt; i+=) e[i].v=e[i^].v=(e[i].v+e[i^].v)>>;
rep(i,l,r) if (mark[a[i]]) tmp[p++]=a[i];
p0=p;
rep(i,l,r) if (!mark[a[i]]) tmp[p++]=a[i];
rep(i,l,r) a[i]=tmp[i];
solve(l,p0-); solve(p0,r);
} int main(){
freopen("bzoj2229.in","r",stdin);
freopen("bzoj2229.out","w",stdout);
for (scanf("%d",&TT); TT--; ){
cnt=; mem(h,); mem(ans,0x3f);
scanf("%d%d",&n,&m);
rep(i,,m) scanf("%d%d%d",&u,&v,&w),add(u,v,w);
rep(i,,n) a[i]=i; solve(,n);
for (scanf("%d",&Q); Q--; ){
scanf("%d",&x); tot=;
rep(i,,n-) rep(j,i+,n) if (ans[i][j]<=x) tot++;
printf("%d\n",tot);
}
puts("");
}
return ;
}
BZOJ4519:
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
#define rep(i,l,r) for (int i=l; i<=r; i++)
#define For(i,x) for (int i=h[x],k; i; i=e[i].nxt)
using namespace std; const int N=,inf=;
int m,n,u,v,w,S,T,tot,cnt=,tmp[N],a[N],b[N],d[N],q[N],h[N];
struct E{ int to,nxt,v; }e[];
bool mark[N]; void add(int u,int v,int w){
e[++cnt]=(E){v,h[u],w}; h[u]=cnt;
e[++cnt]=(E){u,h[v],w}; h[v]=cnt;
} bool bfs(){
memset(d,,sizeof(d)); q[]=S; d[S]=;
for (int st=,ed=; st!=ed; ){
int x=q[++st];
For(i,x) if (e[i].v && !d[k=e[i].to])
d[k]=d[x]+,q[++ed]=k;
}
return d[T];
} int dfs(int x,int lim){
if (x==T) return lim;
int t,c=;
For(i,x) if (d[k=e[i].to]==d[x]+){
t=dfs(k,min(lim-c,e[i].v));
e[i].v-=t; e[i^].v+=t; c+=t;
if (c==lim) return lim;
}
if (!c) d[x]=-; return c;
} int dinic(){ int ans=; while(bfs()) ans+=dfs(S,inf); return ans; } void get(int x){
mark[x]=;
For(i,x) if (!mark[k=e[i].to] && e[i].v) get(k);
} void solve(int l,int r){
if (l==r) return;
S=a[l]; T=a[r]; b[++tot]=dinic();
memset(mark,,sizeof(mark));
get(S); int p=l,p0;
for (int i=; i<=cnt; i+=) e[i].v=e[i^].v=(e[i].v+e[i^].v)>>;
rep(i,l,r) if (mark[a[i]]) tmp[p++]=a[i];
p0=p;
rep(i,l,r) if (!mark[a[i]]) tmp[p++]=a[i];
rep(i,l,r) a[i]=tmp[i];
solve(l,p0-); solve(p0,r);
} int main(){
freopen("bzoj4519.in","r",stdin);
freopen("bzoj4519.out","w",stdout);
scanf("%d%d",&n,&m);
rep(i,,m) scanf("%d%d%d",&u,&v,&w),add(u,v,w);
rep(i,,n) a[i]=i;
solve(,n); sort(b+,b+tot+); tot=unique(b+,b+tot+)-b-;
printf("%d\n",tot);
return ;
}
最小割分治(最小割树):BZOJ2229 && BZOJ4519的更多相关文章
- bzoj2229: [Zjoi2011]最小割(分治最小割+最小割树思想)
2229: [Zjoi2011]最小割 题目:传送门 题解: 一道非常好的题目啊!!! 蒟蒻的想法:暴力枚举点对跑最小割记录...绝对爆炸啊.... 开始怀疑是不是题目骗人...难道根本不用网络流?? ...
- 【bzoj4519】[Cqoi2016]不同的最小割 分治+最小割
题目描述 学过图论的同学都知道最小割的概念:对于一个图,某个对图中结点的划分将图中所有结点分成两个部分,如果结点s,t不在同一个部分中,则称这个划分是关于s,t的割.对于带权图来说,将所有顶点处在不同 ...
- BZOJ 2229 / Luogu P3329 [ZJOI2011]最小割 (分治最小割板题)
题面 求所有点对的最小割中<=c的数量 分析 分治最小割板题 首先,注意这样一个事实:如果(X,Y)是某个s1-t1最小割,(Z,W)是某个s2-t2最小割,那么X∩Z.X∩W.Y∩Z.Y∩W这 ...
- 【BZOJ-4519】不同的最小割 最小割树(分治+最小割)
4519: [Cqoi2016]不同的最小割 Time Limit: 20 Sec Memory Limit: 512 MBSubmit: 393 Solved: 239[Submit][Stat ...
- 最小割树(Gomory-Hu Tree)求无向图最小割详解 附 BZOJ2229,BZOJ4519题解
最小割树(Gomory-Hu Tree) 前置知识 Gomory-Hu Tree是用来解决无向图最小割的问题的,所以我们需要了解无向图最小割的定义 和有向图类似,无向图上两点(x,y)的割定义为一个边 ...
- [ZJOI2011]最小割 & [CQOI2016]不同的最小割 分治求最小割
题面: [ZJOI2011]最小割 [CQOI2016]不同的最小割 题解: 其实这两道是同一道题.... 最小割是用的dinic,不同的最小割是用的isap 其实都是分治求最小割 简单讲讲思路吧 就 ...
- BZOJ 4435 [Cerc2015]Juice Junctions 分治最小割+hash
分治最小割的题目,要求n2. 之前用的n3的方法自然不能用了. 于是用hash,设hash[i][j]表示在最小割为i的时候,j是否与S联通. 看懂这个需要理解一下最小割树的构造. 这种题建议用EK写 ...
- ZJOI 最小割 CQOI 不同的最小割 (最小割分治)
题目1 ZJOI 最小割 题目大意: 求一个无向带权图两点间的最小割,询问小于等于c的点对有多少. 算法讨论: 最小割 分治 代码: #include <cstdlib> #include ...
- POJ3308 Paratroopers(最小割/二分图最小点权覆盖)
把入侵者看作边,每一行每一列都是点,选取某一行某一列都有费用,这样问题就是选总权最小的点集覆盖所有边,就是最小点权覆盖. 此外,题目的总花费是所有费用的乘积,这时有个技巧,就是取对数,把乘法变为加法运 ...
随机推荐
- canvas知识01
本文转自:http://www.cnblogs.com/jsdarkhorse/archive/2012/06/29/2568451.html 更多参考:http://www.cnblogs.com/ ...
- java.sql.Date和java.util.Date的不同和相互转换方式
一:前言 这是我在新的公司写的第一份博客吧,来了又一个星期了吧,但是在来的那几天我真的很迷茫的感觉这里是很不适合我的样子,而且我又是来实习的,我很不愿意啊,自己做的又是java web,最原始的ser ...
- Python基础(4)_集合、布尔类型
一.集合 集合的作用一:关系运算集合的作用二:去重 定义集合:集合内的元素必须是唯一的:集合内的元素必须是可hash的,也是就不可变类型:集合是无序的 s={'egon',123,'egon','1' ...
- 【poj3294-不小于k个字符串中最长公共子串】后缀数组
1.注意每两个串之间的连接符要不一样. 2.分组的时候要注意最后一组啊!又漏了! 3.开数组要考虑连接符的数量.100010是不够的至少要101000. #include<cstdio> ...
- bzoj 1876 高精
首先我们知道,对于两个数a,b,他们的gcd情况有如下形式的讨论 当a为奇数,b为偶数的时候gcd(a,b)=gcd(a div 2,b) 当b为奇数,a为偶数的时候gcd(a,b)=gcd(a,b ...
- Makefile之大型工程项目子目录Makefile的一种通用写法【转】
转自:http://www.cnblogs.com/skyofbitbit/p/3680753.html 管理Linux环境下的C/C++大型项目,如果有一个智能的Build System会起到事半功 ...
- Jmeter接口测试常见的乱码问题三种解决方法
使用Jmeter时经常遇到中文乱码问题,下面总结三种常用的解决方式. 1. 2.在Jmeter安装文件bin中找到jmeter.properties,打开jmeter.properties,搜索“IS ...
- heightCharts改变图表内图标的样式:链接外部图片
series: [{ name: '东京', marker: { symbol: 'url(https://www.highcharts.com/demo/gfx/sun.png)' //链接 ...
- 运行HelloWorld.class是报错(错误: 找不到或无法加载主类 HelloWorld.class)
1.从毕业到现在工作了几个月了,每天都是在写一些js代码,感觉作为一个web程序员,java还是十分重要的,于是自己买了一本java书来边学边练习,然后发现自己连使用记事本来编写的HelloWorld ...
- Selenium2+python自动化53-unittest批量执行(discover)【转载】
前言 我们在写用例的时候,单个脚本的用例好执行,那么多个脚本的时候,如何批量执行呢?这时候就需要用到unittet里面的discover方法来加载用例了. 加载用例后,用unittest里面的Text ...