2 3 2 1 2 1 2 3 1 3 3 1 2 1 2 3 1 1 3 1
Case 1: 1 Case 2: 2
#include<stdio.h>
#include<string.h>
#include<queue>
using namespace std;
#define captype int
const int N = 210;
const int MAX= 1<<30;
struct EDG{
int to,nxt;
captype c; //每条边的残留量
}edg[N*N];
int head[N],eid;
captype vf[N]; //顶点的剩余流量
int h[N]; //顶点的高度
//int n; //顶点个总个数,包含源点与汇点
int min(int a,int b){return a>b?b:a; }
void init(){
memset(head,-1,sizeof(head));
eid=0;
}
//添加 有向边
void addEdg(int u , int v, captype c){
edg[eid].to=v; edg[eid].nxt=head[u]; edg[eid].c=c; head[u]=eid++;
edg[eid].to=u; edg[eid].nxt=head[v]; edg[eid].c=0; head[v]=eid++;
}
captype maxFlow(int sNode,int eNode,int n){//源点与汇点
captype minh,ans=0;
queue<int>q;
memset(h,0,sizeof(h));
memset(vf,0,sizeof(vf));
h[sNode]=n+1; //源点的高度
vf[sNode]=MAX; //源点的余流
q.push(sNode);
while(!q.empty()){
int u=q.front(); q.pop();
minh=MAX;
for(int i=head[u]; i!=-1; i=edg[i].nxt){
int v=edg[i].to;
captype fp;
if(edg[i].c<vf[u])fp=edg[i].c;
else fp=vf[u];
if(fp>0 ){
minh=min(minh, h[v]);
if(u==sNode || h[u]==h[v]+1){
edg[i].c-=fp;
edg[i^1].c+=fp; //反向边,给个反回的通道
vf[u]-=fp;
vf[v]+=fp;
if(v==eNode) ans+=fp; //当到达汇点时,就加入最大流中
if(v!=sNode && v!=eNode ) //只有即不是源点,也不是汇点时才能进队列
q.push(v);
}
}
if(vf[u]==0) break; //如果顶点的余流为0,则可以跳出for循环
}
//如果不是源点(也非汇点),且顶点仍有余流,则重新标记 高度+1 入队
//这里赋值为最低的相邻顶点的高度高一个单位,也可以简单的在原高度+1
if(u!=sNode && vf[u]>0){
h[u] = minh + 1;
q.push(u);
}
}
return ans;
}
int main(){
int T,cas=0,n,m,a,b,c;
scanf("%d",&T);
while(T--){
scanf("%d%d",&n,&m);
init();
while(m--){
scanf("%d%d%d",&a,&b,&c);
addEdg(a,b,c);
}
printf("Case %d: %d\n",++cas,maxFlow(1,n,n));
}
}
原文:http://blog.csdn.net/u010372095/article/details/46446429