给你一个图,图中有多少个顶点、点与点之间的距离(边长)告诉你,求从S点到T点的最大流量是多少?
Sample Input
2
3 2
1 2 1
2 3 1
3 3
1 2 1
2 3 1
1 3 1
3 2
1 2 1
2 3 1
3 3
1 2 1
2 3 1
1 3 1
Sample Output
Case 1: 1
Case 2: 2
Case 2: 2
#include<cstdio>
#include<cstring>
#include<climits>
using namespace std;
#define N 90005
#define M 4000005
#define INF INT_MAX
int s,t,num,pre[N],dis[N],gap[N],head[N],cur[N];
struct node
{
int u,v,w;
int next;
}e[M];
inline void add(int u,int v,int w)
{
e[num].u=u;
e[num].v=v;
e[num].w=w;
e[num].next=head[u];
head[u]=num++;
}
inline void addedge(int u,int v,int w)
{
add(u,v,w);
add(v,u,0);
}
inline int max(int a,int b)
{
return a>b?a:b;
}
inline int min(int a,int b)
{
return a<b?a:b;
}
int isap(int s,int t,int n)
{
int top,mindis,maxflow=0,v,i,aug;
bool flag;
for(i=0;i<=n;i++)
{
cur[i]=head[i];
gap[i]=dis[i]=0;
}
top=pre[s]=s;
aug=INF;
while(dis[s]<n)
{
flag=0;
for(i=cur[top];i!=-1;i=e[i].next)
{
v=e[i].v;
if(e[i].w>0&&dis[top]==dis[v]+1)
{
flag=1;
break;
}
}
if(flag)
{
pre[v]=top;
cur[top]=i;
aug=min(aug,e[i].w);
top=v;
if(top==t)
{
while(top!=s)
{
top=pre[top];
e[cur[top]].w-=aug;
e[cur[top]^1].w+=aug;
}
top=s;
maxflow+=aug;
aug=INF;
}
}
else
{
if(--gap[dis[top]]==0)
break;
mindis=n;
cur[top]=head[top];
for(i=head[top];i!=-1;i=e[i].next)
{
v=e[i].v;
if(e[i].w>0&&dis[v]+1<mindis)
{
mindis=dis[v]+1;
cur[top]=i;
}
}
dis[top]=mindis;
gap[mindis]++;
if(top!=s)
top=pre[top];
}
}
return maxflow;
}
void init()
{
num=0;
memset(head,-1,sizeof(head));
}
int main()
{
int nodenum,m,n,test;
scanf("%d",&test);
for(int ii=1;ii<=test;ii++)
{
scanf("%d%d",&n,&m);
init();
while(m--)
{
int u,v,w;
scanf("%d%d%d",&u,&v,&w);
addedge(u,v,w);
}
//source=1,sink=n,nodenum=n;
int res=isap(1,n,n);
printf("Case %d: %d\n",ii,res);
}
return 0;
}
另一种方法:
#include <iostream>
#include <queue>
using namespace std;
const int N = 210;
const int INF = 0x7FFFFFFF;
int n,m,map[N][N],path[N],flow[N],start,end;
queue<int> q;
int bfs(){
int i,t;
while(!q.empty()) q.pop();
memset(path,-1,sizeof(path));
path[start]=0,flow[start]=INF;
q.push(start);
while(!q.empty()){
t=q.front();
q.pop();
if(t==end) break;
for(i=1;i<=m;i++){
if(i!=start && path[i]==-1 && map[t][i]){
flow[i]=flow[t]<map[t][i]?flow[t]:map[t][i];
q.push(i);
path[i]=t;
}
}
}
if(path[end]==-1) return -1;
return flow[m]; //一次遍历之后的流量增量
}
int Edmonds_Karp(){
int max_flow=0,step,now,pre;
while((step=bfs())!=-1){ //找不到增路径时退出
max_flow+=step;
now=end;
while(now!=start){
pre=path[now];
map[pre][now]-=step; //更新正向边的实际容量
map[now][pre]+=step; //添加反向边
now=pre;
}
}
return max_flow;
}
int main(){
int i,u,v,cost;
while(scanf("%d %d",&m,&n)!=EOF){
if(!n&&!m)
return 0 ;
memset(map,0,sizeof(map));
for(i=0;i<n;i++){
scanf("%d %d %d",&u,&v,&cost);
map[u][v]+=cost; //not just only one input
}
start=1,end=m;
printf("%d\n",Edmonds_Karp());
}
return 0;
}