最大流——EK演算法
阿新 • • 發佈:2019-01-09
EK演算法是求最大流的一種容易實現、程式碼易懂的演算法。
EK演算法仍然是一個基於增廣路的演算法,思路非常簡單。每次從S嘗試找到一條到達T的路徑,路徑上最小的殘留量大於0,那麼我們就可以把這條路上的最小殘留量減去,累加到ans裡。繼續bfs直到找不到位置,此時ans就是最大流。
EK增廣路演算法的時間複雜度為O(nm^2)。但是在實際運營中遠遠達不到這個上界,效率較高,一般認為,可以處理10^3~10^4內規模的網路。
//??????EK?? #include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<queue> const int inf=1<<29,N=2010,M=20010; int n,m,s,t,tot,maxflow,ver[M],edge[M],Next[M],v[N],lin[N],incf[N],pre[N]; using namespace std; void add(int x,int y,int c){ ver[++tot]=y;Next[tot]=lin[x];edge[tot]=c;lin[x]=tot; ver[++tot]=x;Next[tot]=lin[y];edge[tot]=0;lin[y]=tot; } bool bfs(){ memset(v,0,sizeof(v)); queue<int>q; q.push(s),v[s]=1; incf[s]=inf; while(q.size()){ int x=q.front();q.pop(); for(int i=lin[x];i;i=Next[i]){ if(edge[i]){ int y=ver[i]; if(v[y]) continue; incf[y]=min(incf[x],edge[i]); pre[y]=i; q.push(y),v[y]=1; if(y==t) return 1; } } } return 0; } void update(){ int x=t; while(x!=s){ int i=pre[x]; edge[i]-=incf[t]; edge[i^1]+=incf[t]; x=ver[i^1]; } maxflow+=incf[t]; } int main(){ while(cin>>n>>m){ memset(lin,0,sizeof(lin)); s=1,t=n;tot=1,maxflow=0; for(int i=1;i<=m;++i){ int x,y,c;scanf("%d%d%d",&x,&y,&c); add(x,y,c); } while(bfs()) update(); printf("%d\n",maxflow); } return 0; }