5 4 1 2 40 1 4 20 2 4 20 2 3 30 3 4 10
50
求源点1到汇点m的最大流 ek算法
第一次最大流。。。
#include<iostream> #include<cstdio> #include<cstring> #include<cmath> #include<queue> using namespace std; #define INF 0x3f3f3f3f #define ll long long int main() { int n,m; while(~scanf("%d%d",&n,&m)) { int c[205][205],f[205][205]; int vis[205],p[205]; queue<int >q; memset(c,0,sizeof(c)); //c标记容量 memset(f,0,sizeof(f)); //f标记流量 for(int i=0;i<n;i++) { int aa,bb,cc; scanf("%d%d%d",&aa,&bb,&cc); if(aa!=bb) c[aa][bb]+=cc; //可能会有重复边 } int ff=0; while(1) { memset(vis,0,sizeof(vis)); //记录当前点的流量 memset(p,-1,sizeof(p)); //记录当前点的前驱 vis[1]=INF; q.push(1); while(q.size()) { int st=q.front(); q.pop(); for(int i=1;i<=m;i++) { if(!vis[i]&&f[st][i]<c[st][i]) { vis[i]=min(vis[st],c[st][i]-f[st][i]); //流量为当前路径的最大流量或者为当前点的最大流量 p[i]=st; //记录前驱 q.push(i); } } } if(!vis[m]) break; for(int i=m;i!=1;i=p[i]) { f[p[i]][i]+=vis[m]; f[i][p[i]]-=vis[m]; } ff+=vis[m]; } printf("%d\n",ff); } }
#include<iostream> #include<cstdio> #include<cstring> #include<cmath> #include<queue> using namespace std; #define INF 0x3f3f3f3f #define ll long long int main() { int n,m; int t,tt=1; int c[205][205],f[205]; bool vis[205]; int p[205]; queue<int >q; //scanf("%d",&t); while(~scanf("%d%d",&n,&m)) { memset(c,0,sizeof(c)); //c标记容量 for(int i=0; i<n; i++) { int aa,bb,cc; scanf("%d%d%d",&aa,&bb,&cc); //if(aa!=bb) c[aa][bb]+=cc; //可能会有重复边 } int ff=0; while(1) { memset(vis,false ,sizeof(vis)); //记录当前点的流量 memset(p,-1,sizeof(p)); //记录当前点的前驱 for(int i=1;i<=m;i++) f[i]=INF; vis[1]=true ; while(q.size()) q.pop(); q.push(1); while(q.size()) { int st=q.front(); q.pop(); if(st==m) break; for(int i=1; i<=m; i++) { if(!vis[i]&&c[st][i]>0) { vis[i]=true ; f[i]=min(f[st],c[st][i]); //流量为当前路径的最大流量或者为当前点的最大流量 p[i]=st; //记录前驱 q.push(i); } } } if(!vis[m]) break; //cout<<f[n]<<endl; int st=m; while(st!=1) { int ed=p[st]; c[ed][st]-=f[m]; //正向边 c[st][ed]+=f[m]; //反向边 st=ed; } ff+=f[m]; } printf("%d\n",ff); } }