最大流Dinic
阿新 • • 發佈:2020-12-30
最近被濟南打自閉了,要學習一波圖論和數學方面的知識了
推薦一波大佬的知乎
一道模板題
洛谷p1343
將人看成流量
所以每次最多的人數就相當於求一次最大流就OK了
#include<bits/stdc++.h> using namespace std; using ll = long long; const int INF = INT_MAX; struct Edge{ int to, c; int next; Edge(){ to = 0; c = 0; next = 0; }; }; const int MAXN= 1e4+10; const int N = 205; Edge edges[MAXN]; int head[N]; int cnt =1; void add(int from, int to, int c){ cnt += 1; edges[cnt].to = to; edges[cnt].next = head[from]; edges[cnt].c = c; head[from] = cnt; } int s,t; int n,m; int level[N], cur[N]; bool bfs(){ //當前的圖進行分層 memcpy(cur, head, sizeof head); memset(level, -1, sizeof level); level[s]=0; queue<int> que; que.push(s); while(!que.empty()){ int p = que.front(); que.pop(); for(int eg=head[p]; eg; eg=edges[eg].next){ int to = edges[eg].to, c = edges[eg].c; if(c && level[to]==-1) level[to]=level[p]+1, que.push(to); } } return level[t]!=-1; } int dfs(int p=s, int flow = INF){ if(p==t) return flow; int rem = flow; for(int eg = cur[p]; eg&&rem; eg = edges[eg].next){ cur[p]=eg; //被增廣過的邊不會再被增廣,因為分層之後儘量使用的 int to = edges[eg].to, c = edges[eg].c; if(c && level[to]==level[p]+1){ //往下一層增廣 int c_flow = dfs(to, min(c, rem)); //管道內的較小的被限制 rem -= c_flow; edges[eg].c -= c_flow; edges[eg^1].c += c_flow; } } return flow - rem;//增廣掉的流量就是流 } ll dinic(){ ll ans = 0; while(bfs()){ ans += dfs(); } return ans; } int main(){ // freopen("in.dat", "r", stdin); memset(head, 0, sizeof head); int x; cin>>n>>m>>x; s = 1; t = n; int from, to, c; for(int i=0; i<m; i++){ cin>>from>>to>>c; add(from, to, c); add(to, from, 0); } ll ans = dinic(); if(ans==0){ cout<<"Orz Ni Jinan Saint Cow!"<<endl; return 0; } cout<<ans<<" "<<(x/ans + (x%ans!=0))<<endl; return 0; }