最小割分治(最小割树):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(最小割/二分图最小点权覆盖)
把入侵者看作边,每一行每一列都是点,选取某一行某一列都有费用,这样问题就是选总权最小的点集覆盖所有边,就是最小点权覆盖. 此外,题目的总花费是所有费用的乘积,这时有个技巧,就是取对数,把乘法变为加法运 ...
随机推荐
- 停课day2
感觉今天好颓啊,我才把昨晚那五道题a了,(但我明明一直在学啊,为啥这么慢,难道是我太笨了?) 闲话少叙,先说做法 问题 A: C Looooops 题目描述 对于C的for(i=A ; i!=B ;i ...
- [SCOI2007] 蜥蜴 (最大流)
[SCOI2007] 蜥蜴 题目背景 07四川省选 题目描述 在一个r行c列的网格地图中有一些高度不同的石柱,一些石柱上站着一些蜥蜴,你的任务是让尽量多的蜥蜴逃到边界外. 每行每列中相邻石柱的距离为1 ...
- jquery中的get和post、ajax有关返回值的问题描述
一:前言 今天我就要离开公司回学校准备考试,在走之前,我自己做的一个模块测试除了一些小的bug.问题如下 我在往数据库中插入数据,首先要选择一级菜单,接着会更具一级菜单生成一级菜单的子目录,在选择日期 ...
- WEB-INF 有关的目录路径问题总结
1.资源文件只能放在WebContent下面,如 CSS,JS,image等.放在WEB-INF下引用不了. 2.页面放在WEB-INF目录下面,这样可以限制访问,提高安全性.如JSP,html 3. ...
- java深入解析
具体内容安排如下: Java Collections Framework概览 对Java Collections Framework,以及Java语言特性做出基本介绍. Java ArrayList源 ...
- BZOJ1082_栅栏_C++
题目:http://www.lydsy.com/JudgeOnline/problem.php?id=1082 题解:http://www.cnblogs.com/hadilo/p/5924546.h ...
- js没有重载
javascript与其他语言(如java)不同,它没有传统意义上的重载(即为函数编写两个定义,只要这两个函数的参数类型或数量不同即可),在js中,后定义的函数会覆盖先前的函数.js中的参数在内部是用 ...
- JSP页面中格式化日期为指顶格式
有时候在页面中显示直接从数据库获取的日期时候会出现英文的日期格式.比如:
- 包与time,datetime,random,sys,shutil 模块
一.包 包是什么? 包是一种通过使用‘.模块名’来组织python模块名称空间的方式. 注意: 1. 在python3中,即使包下没有__init__.py文件,import 包仍然不会报错,而在py ...
- UVALIVE 3562 Remember the A La Mode!
费用流 建图很简单直接上代码 #include <map> #include <set> #include <list> #include <cmath> ...