网络流--Dinic(自用,勿看)
注意:这是一篇个人学习笔记,如果有人因为某些原因点了进来并且要看一下,请一定谨慎地阅读,因为可能存在各种奇怪的错误,如果有人发现错误请指出谢谢!
https://www.luogu.org/problemnew/show/P3376
来自蓝书:
时间复杂度O(n^2*m)
所有容量均为1,可以证明时间复杂度O(min(n^(2/3),m^(1/2))*m)
除了源点和汇点之外,每个点要么只有一条入弧,且容量为1,要么只有一条出弧,且容量为1,其他弧的容量为任意整数,可以证明时间复杂度O(n^(1/2)*m)
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include<cstdio> 2 #include<algorithm> 3 #include<cstring> 4 #include<vector> 5 #include<queue> 6 using namespace std; 7 #define fi first 8 #define se second 9 #define mp make_pair 10 #define pb push_back 11 typedef long long ll; 12 typedef unsigned long long ull; 13 typedef pair<int,int> pii; 14 namespace F 15 { 16 17 struct E 18 { 19 int to,nxt,from,cap,flow; 20 }e[200100]; 21 int f1[10100],ne=1; 22 int S,T,n; 23 int d[10100]; 24 void clr(int n) 25 { 26 ne = 1; 27 memset(f1, 0, sizeof(f1[0]) * (n+5)); 28 } 29 bool bfs() 30 { 31 int k,u; 32 memset(d,0,sizeof(int)*(n+1)); 33 queue<int> q; 34 q.push(S);d[S]=1; 35 while(!q.empty()) 36 { 37 u=q.front();q.pop(); 38 for(k=f1[u];k;k=e[k].nxt) 39 if(!d[e[k].to]&&e[k].cap>e[k].flow) 40 { 41 d[e[k].to]=d[u]+1; 42 //if(e[k].to==T) return 1; 43 q.push(e[k].to); 44 } 45 } 46 //return 0; 47 return d[T]; 48 } 49 int cur[10100]; 50 int dfs(int u,int x) 51 { 52 if(u==T||x==0) return x; 53 int flow=0,f; 54 for(int &k=cur[u];k;k=e[k].nxt) 55 if(e[k].cap>e[k].flow&&d[e[k].to]==d[u]+1) 56 { 57 f=dfs(e[k].to,min(x-flow,e[k].cap-e[k].flow)); 58 e[k].flow+=f;e[k^1].flow-=f;flow+=f; 59 if(flow==x) return flow; 60 } 61 return flow; 62 } 63 int solve() 64 { 65 int flow=0; 66 while(bfs()) 67 { 68 memcpy(cur,f1,sizeof(int)*(n+1)); 69 flow+=dfs(S,0x3f3f3f3f); 70 } 71 return flow; 72 } 73 void me(int a,int b,int c) 74 { 75 e[++ne].to=b;e[ne].nxt=f1[a];f1[a]=ne; 76 e[ne].from=a;e[ne].cap=c;e[ne].flow=0; 77 e[++ne].to=a;e[ne].nxt=f1[b];f1[b]=ne; 78 e[ne].from=b;e[ne].cap=0;e[ne].flow=0; 79 } 80 81 } 82 int n,m; 83 int main() 84 { 85 int i,a,b,c; 86 scanf("%d%d%d%d",&n,&m,&F::S,&F::T);F::n=n; 87 for(i=1;i<=m;i++) 88 { 89 scanf("%d%d%d",&a,&b,&c); 90 F::me(a,b,c); 91 } 92 printf("%d",F::solve()); 93 return 0; 94 }
upd2022.08.19 出于多组数据的需要做出了相应修改
(补上37行,42行改成41行,跑的要更快,但是感觉不太对所以没有写)