bzoj4519 [Cqoi2016]不同的最小割 分治最小割 模板
来源:互联网 发布:穿越火线fps优化器 编辑:程序博客网 时间:2024/09/21 09:28
题目大意:
给一张图,求任意两点最小割有多少不同的值。
题目分析:
分治最小割的模板题。
分治最小割可以在O(n次网络流+n^2)的时间复杂度求出任意两个点之间的最小割。
我也不知道为什么但是这么做是对的QWQ。
对于分治的序列,随便选择两个点作为源点和汇点,跑一遍网络流。
在S和T之间连一条流量为最小割的边。
然后和S连通的点分到左边,剩余的点分到右边,递归下去。
这样做我们会做n-1次网络流,并且每次填一条边,这样就得到了一棵树(就是所谓的最小割树)
任意两个点为源和汇的最小割就是在最小割树上这两个点路径上的最小值。
O(n^2)就可以统计出来。
然后就随便统计一下不同的值就行了~
代码如下:
#include <cstdio>#include <cstring>#include <algorithm>#define N 900#define M 22000using namespace std;const int INF=0x3f3f3f3f;inline int Min(int x,int y) { return x<y?x:y; }int n,m;namespace Minimum_Cut_Tree{ int fir[N],nes[N<<1],v[N<<1],q[N<<1],tot=1; int a[N*N],top; void edge(int x,int y,int z) { v[++tot]=y; q[tot]=z; nes[tot]=fir[x]; fir[x]=tot; } inline void Edge(int x,int y,int z) { edge(x,y,z); edge(y,x,z); } void dfs(int c,int fa,int num) { for(int t=fir[c];t;t=nes[t]) { if(v[t]==fa) continue; a[top++]=Min(num,q[t]); dfs(v[t],c,Min(num,q[t])); } } int work() { for(int i=1;i<=n;i++) dfs(i,0,INF); sort(a,a+top); return unique(a,a+top)-a; }}namespace Network_Flow{ int S,T; int fir[N],nes[M],v[M],q[M],tot=1; int d[N],dl[N],a[N],tmp[N]; void edge(int x,int y,int z) { v[++tot]=y; q[tot]=z; nes[tot]=fir[x]; fir[x]=tot; } void Edge(int x,int y,int z) { edge(x,y,z); edge(y,x,z); } void init() { for(int i=2;i<=tot;i+=2) q[i]=q[i^1]=q[i]+q[i^1]>>1; } bool bfs() { static int c; int l=1,r=1; memset(d,0,sizeof(d)); dl[1]=S; d[S]=1; while(l<=r) { c=dl[l++]; for(int t=fir[c];t;t=nes[t]) { if(!q[t] || d[v[t]]) continue; d[v[t]]=d[c]+1; dl[++r]=v[t]; if(v[t]==T) return true; } } return false; } int dfs(int c,int flow) { if(c==T || flow==0) return flow; int ans=0; for(int t=fir[c];t;t=nes[t]) { if(!q[t] || d[v[t]]!=d[c]+1) continue; int tmp=dfs(v[t],Min(q[t],flow)); q[t]-=tmp; q[t^1]+=tmp; flow-=tmp; ans+=tmp; if(!flow) break; } if(!ans) d[c]=-1; return ans; } int dinic() { int ans=0; while(bfs()) ans+=dfs(S,INF); return ans; } void divide_and_conquer(int l,int r) { if(l>=r) return; init(); S=a[l]; T=a[r]; Minimum_Cut_Tree :: Edge(S,T,dinic()); bfs(); int _l=l-1,_r=r+1; for(int i=l;i<=r;i++) if(d[a[i]]) tmp[++_l]=a[i]; else tmp[--_r]=a[i]; for(int i=l;i<=r;i++) a[i]=tmp[i]; divide_and_conquer(l,_l); divide_and_conquer(_r,r); } void work() { for(int i=1,x,z,y;i<=m;i++) { scanf("%d%d%d",&x,&y,&z); Edge(x,y,z); } for(int i=1;i<=n;i++) a[i]=i; divide_and_conquer(1,n); }}int main(){ scanf("%d%d",&n,&m); Network_Flow :: work(); printf("%d\n",Minimum_Cut_Tree :: work()); return 0;}
阅读全文
0 0
- bzoj4519 [Cqoi2016]不同的最小割 分治最小割 模板
- Bzoj4519:[Cqoi2016]不同的最小割:分治最小割
- CQOI2016 bzoj4519 不同的最小割cuts
- 【CQOI2016】【BZOJ4519】不同的最小割
- bzoj4519【CQOI2016】不同的最小割
- BZOJ4519: [Cqoi2016]不同的最小割
- bzoj4519[Cqoi2016]不同的最小割
- BZOJ4519——[cqoi2016]不同的最小割
- 【分治最小割】[CQOI2016]不同的最小割
- [分治最小割] BZOJ 4519 [Cqoi2016]不同的最小割
- bzoj 4519: [Cqoi2016]不同的最小割 分治&最小割
- CQOI2016 不同的最小割 分治最小割(最小割树)
- BZOJ 4519 [Cqoi2016]不同的最小割 最小割树(分治最小割)
- BZOJ 4519: [Cqoi2016]不同的最小割 最小割树 / 分治最小割
- [BZOJ4519] 不同的最小割 - 分治,最小割(Gomory-Hu Tree)
- [CQOI2016]不同的最小割
- 【BZOJ2229】最小割【BZOJ4519】不同的最小割
- bzoj 4519: [Cqoi2016]不同的最小割 最小割树
- Tomcat配置虚拟路径使上传文件和服务器分离及上传文件
- Linux for Ubuntu 国产音乐客户端(网易云)
- git 命令总结
- html 缩写
- golang faygo 框架模板的简单使用
- bzoj4519 [Cqoi2016]不同的最小割 分治最小割 模板
- C++设计模式十--TemplatePattern(模板方法模式)
- 数据结构--概述
- Intent传递List<object>方法
- python之html转docx文件高级用法---使用样式
- 杂谈 | 移动互联网行业迎来存量经营时代(一)——宏观环境
- 如何保护你的隐私(一)
- 数据字典设计实现缓存
- 前端入门篇