最小割分治(最小割树):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(最小割/二分图最小点权覆盖)
把入侵者看作边,每一行每一列都是点,选取某一行某一列都有费用,这样问题就是选总权最小的点集覆盖所有边,就是最小点权覆盖. 此外,题目的总花费是所有费用的乘积,这时有个技巧,就是取对数,把乘法变为加法运 ...
随机推荐
- bcc
#include<bits/stdc++.h> using namespace std; #define mxn 510 struct E{ int from,to; }; int dfn ...
- HttpClient测试类请求端和服务端即可能出现乱码的解决
junit HttpClient 请求端 代码: package com.taotao.httpclient; import java.util.ArrayList; import java.util ...
- POJ 2398 Toy Storage 二分+叉积
Description Mom and dad have a problem: their child, Reza, never puts his toys away when he is finis ...
- POJ 2456 Aggressive cows---二分搜索法
///3.最大化最小值 /** POJ 2456 Aggressive cows Q:一排牛舍有N (2 <= N <= 100,000) 个,位置为x1,...,xN (0 <= ...
- 一维和二维ST模板
void init(){ ; i < n; i++) st[i][] = a[i]; ; ( << j) <= n; j++){ ; i + ( << j) - & ...
- [NOIp普及组2011]瑞士轮
洛谷题目链接:瑞士轮 题目背景 在双人对决的竞技性比赛,如乒乓球.羽毛球.国际象棋中,最常见的赛制是淘汰赛和循环赛.前者的特点是比赛场数少,每场都紧张刺激,但偶然性较高.后者的特点是较为公平,偶然性较 ...
- Python基础(1)_初识Python
一.为什么要编程 解放人力:让机器按照人们事先为其编写好的程序自发地去工作 二.什么是编程语言 编程语言就是程序员与计算机之间沟通的介质:程序员把自己想说的话用编程语言写到文件里,这其实就开发了一个程 ...
- Spring - IoC(5): 集合属性的注入
如果 Bean 的属性是个集合,则可以使用 <list/>.<set/>.<map/> 和 <props/> 元素向 List.Set.Map 和 Pr ...
- SVG布局
http://www.w3cplus.com/html5/nesting-svgs.html
- Vue 还是 React 还是 Angular ?
有空的时候还是把3个都熟悉一下.除了Angular学习起来笔记花时间外.React跟Vue没啥难度,学习用的时间不多. 如果你在Google工作:Angular如果你喜欢TypeScript:Angu ...