最大流问题(讲的不错)
#include<stdio.h>
#include<string.h>
#define N 500
#define inf 10000
int min(int a,int b){
return a<b?a:b;
}
int r[N][N],n,flow;//残留网络,初始化为原图
int vis[N],pre[N],Q[N];//标记在这条路径上当前节点的前驱,同时标记该节点是否在队列中
int bfs(int s,int t){//寻找一条从s到t的增广路, s为源点,t为汇点
memset(vis,0,sizeof(vis));
memset(pre,-1,sizeof(pre)); //初始化前驱
memset(Q,0,sizeof(Q));//队列清空
int front,rear;
front=0,rear=1;
vis[s]=1;
pre[s]=s;
Q[front]=s;
while(front<rear){
int p=Q[front++];
for(int i=1;i<=n;i++){//遍历所有的结点
if(r[p][i]>0&&!vis[i]){//只有残留容量大于0时才存在边
pre[i]=p;//记录前驱
vis[i]=1;
if(i==t) return 1;//找到一条从s到t的增广路返回1
Q[rear++]=i;//把下一个节点放到队列里
}
}
}
return 0;
}
int EdmondsKarp(int s,int t){
int flow=0,d,i;
while(bfs(s,t)){
d=inf;//初始化源点的流量为无穷大
for(i=t;i!=s;i=pre[i]){
d=min(d,r[pre[i]][i]);//求出残留容量的最小值。
}
for(i=t;i!=s;i=pre[i]){
r[pre[i]][i]-=d;//改变正向边的容量
r[i][pre[i]]+=d;//改变反向边的容量
}
flow+=d;
}
return flow;
}
int main(){
int m,t,i,j,a,b,val,k;
scanf("%d",&t);
k=1;
while(t--){
memset(r,0,sizeof(r));
scanf("%d%d",&n,&m);
for(i=0;i<m;i++){
scanf("%d%d%d",&a,&b,&val);//重边叠加
r[a][b]+=val;
}
printf("Case %d: %d\n",k++,EdmondsKarp(1,n));
}
}