网络流二·最大流最小割定理(Dinic模板+dfs/bfs找S集合模板)
Posted wsy107316
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了网络流二·最大流最小割定理(Dinic模板+dfs/bfs找S集合模板)相关的知识,希望对你有一定的参考价值。
网络流二·最大流最小割定理
AC_Code:
1 #include <bits/stdc++.h> 2 #include <ctime> 3 #include <algorithm> 4 #include <random> 5 using namespace std; 6 typedef long long ll; 7 typedef unsigned long long ull; 8 const int maxn = 2e4+10; 9 const int inf = 0x3f3f3f3f; 10 #define gok ios::sync_with_stdio(false);cin.tie(0);cout.tie(0) 11 #define pii pair<int,int> 12 #define fi first 13 #define se second 14 #define pb push_back 15 #define rep(i,first,second) for(int i=first;i<=second;i++) 16 #define dep(i,first,second) for(int i=first;i>=second;i--) 17 #define erep(i,u) for(int i=head[u];~i;i=e[i].nxt) 18 19 struct node{int to,nxt,c;}e[maxn<<1]; 20 int head[maxn<<1],tot,dep[maxn]; 21 bool vis[maxn]; 22 int n,m,cnt; 23 24 void add(int u,int v,int w){ 25 e[tot].to=v; 26 e[tot].c=w; 27 e[tot].nxt=head[u]; 28 head[u]=tot++; 29 } 30 void addedge(int u,int v,int w){add(u,v,w),add(v,u,0);} 31 bool bfs(int st,int ed){ 32 memset(dep,-1,sizeof(dep)); 33 queue<int>que; 34 while( !que.empty()) que.pop(); 35 que.push(st); 36 dep[st]=0; 37 int u; 38 while( !que.empty()){ 39 u=que.front();que.pop(); 40 erep(i,u){ 41 int v=e[i].to; 42 if( dep[v]==-1 && e[i].c>0 ){ 43 dep[v]=dep[u]+1; 44 que.push(v); 45 if( v==ed ) return true; 46 } 47 48 } 49 } 50 return dep[ed]!=-1; 51 } 52 int dfs(int st,int ed,int flow){ 53 if( st==ed || flow==0 ) return flow; 54 int curr=0; 55 erep(i,st){ 56 int v=e[i].to; 57 int val=e[i].c; 58 if( dep[st]+1==dep[v] && val>0 ){ 59 int d=dfs(v,ed,min(val,flow)); 60 if( d>0 ){ 61 e[i].c-=d;e[i^1].c+=d; 62 curr+=d;flow-=d; 63 if( flow==0 ) break; 64 } 65 } 66 } 67 if( curr==0 ) dep[st]=inf; 68 return curr; 69 } 70 71 int Dinic(int st,int ed){ 72 int flow=0; 73 while( bfs(st,ed) ){ 74 flow+=dfs(st,ed,inf); 75 } 76 return flow; 77 } 78 /* 79 void new_bfs(int st){ //bfs找S 80 memset(vis,0,sizeof(vis)); 81 dep[st]=0; 82 vis[st]=1; 83 queue<int>que; 84 while( !que.empty()) que.pop(); 85 que.push(st); 86 while( !que.empty()){ 87 int u=que.front();que.pop(); 88 erep(i,u){ 89 int v=e[i].to; 90 int val=e[i].c; 91 if( !vis[v] && val>0){ 92 vis[v]=1; 93 dep[v]=dep[u]+1; 94 que.push(v); 95 } 96 } 97 } 98 } 99 */ 100 void new_dfs(int u){ //dfs找S 101 vis[u]=1; 102 erep(i,u){ 103 int v=e[i].to; 104 int val=e[i].c; 105 if( !vis[v] && val>0 ){ 106 new_dfs(v); 107 } 108 } 109 } 110 111 int main() 112 { 113 memset(head,-1,sizeof(head)); 114 tot=0; 115 scanf("%d%d",&n,&m); 116 rep(i,1,m){ 117 int u,v,cap; 118 scanf("%d%d%d",&u,&v,&cap); 119 addedge(u,v,cap); 120 } 121 int flow=Dinic(1,n); 122 new_dfs(1); 123 124 printf("%d ",flow); 125 rep(i,1,n){ 126 if( vis[i] ) cnt++; 127 } 128 printf("%d ",cnt); 129 rep(i,1,n){ 130 if( vis[i] ) printf("%d ",i); 131 } 132 printf(" "); 133 return 0; 134 }
以上是关于网络流二·最大流最小割定理(Dinic模板+dfs/bfs找S集合模板)的主要内容,如果未能解决你的问题,请参考以下文章
hihoCoder 1378 网络流二·最大流最小割定理 (网络流学习#2 记录)
hiho一下 第119周 #1398 : 网络流五·最大权闭合子图 最小割-最大流--Ford-Fulkerson 与 Dinic 算法