網絡最大流 dinic算法
阿新 • • 發佈:2017-05-26
next 發生 mem bfs light ont ems ++ set
一句話題意:給出一個網絡圖,以及其源點和匯點,求出其網絡最大流
//dinic算法; //時間復雜度O(V^2E); #include<bits/stdc++.h> #define inf 999999 #define maxn 200000 using namespace std; int n,m,s,t; int ans=0; struct Edge { int to,next,w; }; struct Edge edge[maxn]; int head[maxn],val[maxn],pre[maxn]; int level[maxn]; int cnt=0; void add(int u,int v,int w)//前向星儲存邊 { edge[cnt].to=v; edge[cnt].w=w; edge[cnt].next=head[u]; head[u]=cnt++; } int bfs(int s,int t) { queue<int> q; q.push(s); memset(level,-1,sizeof(level));//一定要從-1開始儲存,如果從0開始存的話由於數組本身就是0,會造成死循環!! level[s]=0; while(!q.empty()) { int j=q.front();q.pop(); for(int i=head[j];~i;i=edge[i].next) { int v=edge[i].to; if(level[v]==-1&&edge[i].w)//染色,廣搜求出到達每個點的步數 { level[v]=level[j]+1; q.push(v); } } } return (level[t]==-1) ? 0 : 1;//如果不能達到t就是沒有增廣路,就不進行查找 } int dfs(int u,int flow,int v) { if(u==v) return flow; int rest=0; for(int i=head[u];~i;i=edge[i].next) { int j=edge[i].to; if(level[u]+1==level[j]&&edge[i].w) { int flo=dfs(j,min(edge[i].w,flow-rest),v); rest+=flo; edge[i].w-=flo; edge[i^1].w+=flo;//如果i=0,則去i+1如果i=1則取0,總之是取反向邊 } } if(!rest) level[u]=-1; return rest; } int main() { int u,v,w; memset(head,-1,sizeof(head)); cin>>n>>m>>s>>t; for(int i=0;i<m;i++)//註意從0開始儲存,否則會發生錯誤 { cin>>u>>v>>w; add(u,v,w);//s->t存到2k add(v,u,0);//t->s存到2k-1 } while(bfs(s,t)) while(int tmp=dfs(s,inf,t)) ans+=tmp; cout<<ans<<endl; return 0; }
網絡最大流 dinic算法