模拟后项弧 #include <stdio.h> #include <string.h> #define N 202 #define INF 0x3fffffff #define _cls(a) memset(a,0,sizeof(a)) int f[N][N];//current flow int c[N][N];//capacity int mark[N];// 0 -1 1 搜索过 bool vis[N];//标记过 int prev[N];//前继 int d[N];//当前增加的flow int qu[N];//BFS queue int Min (int a,int b) { return a>b? b:a; } int max_flow(int n,int s,int t)//souce sink { int top,base,u,v,flow=0; _cls(f); do { _cls(d); _cls(mark); _cls(vis); qu[0]=s; vis[s]=1; d[s]=INF; for (base=0,top=1;base!=top && !vis[t];)//bfs 如果sink被标记就结束 { for (u=qu[base],v=1;v<=n;v++) { if (!vis[v])//对每个未被标记的点 { vis[v]=1; if (c[u][v] && f[u][v]<c[u][v])//如果(u,v)存在 flow而且没有满 { d[v]=Min(d[u],c[u][v]-f[u][v]); mark[v]=1; prev[v]=u; qu[top++]=v; } else if (f[v][u])//反向弧 沿弧的反方向抵消原来的flow { d[v]=Min(d[u],f[v][u]); mark[v]=-1; prev[v]=u; qu[top++]=v; } else vis[v]=0;//如果以上2项都不符合 不算visited } } base++; } if (!vis[t]) break;//没有增广路了 flow+=d[t]; //printf("++%d ",d[t]); for (u=t;u!=s;)//倒回去 增加增广路上的flow { v=u; //printf("%c ",v+'A'-1); u=prev[v]; f[u][v]+=d[t]*mark[v]; } //printf("/n"); }while(d[t]>0); return flow; } int main () { //freopen("1273.txt","r",stdin); int n,m,a,b,w; while(scanf("%d%d",&m,&n)!=EOF) { _cls(c); while(m--) { scanf("%d%d%d",&a,&b,&w); c[a][b]+=w;//有相同flow多次 } printf("%d/n",max_flow(n,1,n)); } } 有后项弧 #include <stdio.h> #include <string.h> #define N 202 #define INF 0x3fffffff #define _cls(a) memset(a,0,sizeof(a)) int c[N][N];//当前 capacity bool vis[N];//标记过 int prev[N];//前继 int d[N];//当前增加的flow int qu[N];//BFS queue int Min (int a,int b) { return a>b? b:a; } int max_flow(int n,int s,int t)//souce sink { int top,base,u,v,flow=0; do { _cls(d); _cls(vis); qu[0]=s; vis[s]=1; d[s]=INF; for (base=0,top=1;base!=top && !vis[t];)//bfs 如果sink被标记就结束 { for (u=qu[base],v=1;v<=n;v++) { if (!vis[v] && c[u][v])//对每个未被标记的点 { vis[v]=1; d[v]=Min(d[u],c[u][v]); prev[v]=u; qu[top++]=v; } } base++; } if (!vis[t]) break;//没有增广路了 flow+=d[t]; //printf("++%d ",d[t]); for (u=t;u!=s;)//倒回去 增加增广路上的flow { v=u; //printf("%c ",v+'A'-1); u=prev[v]; c[u][v]-=d[t]; c[v][u]+=d[t];//后项弧 } //printf("/n"); }while(d[t]>0); return flow; } int main () { //freopen("1273.txt","r",stdin); int n,m,a,b,w; while(scanf("%d%d",&m,&n)!=EOF) { _cls(c); while(m--) { scanf("%d%d%d",&a,&b,&w); c[a][b]+=w;//有相同flow多次 } printf("%d/n",max_flow(n,1,n)); } } 12 71 2 51 3 71 4 42 3 12 6 33 4 23 5 53 6 44 5 4 等于14