题目链接:http://poj.org/problem?id=1273
题目意思:John是一个农户,每到下雨天,John的农田就淹成了一个水塘,John就在M(2 <= M<=200)个点之间挖了N(0<=N<=200)条沟渠,把水排到小溪里,其中1号点在农田,M号点在小溪。
思路:直接取1号点为源点,M号点为汇点。基本构图,然后套用EK的模版即可!
代码:
#include<stdio.h>
#include<string.h>
#define INF 0x7fffffff
#define MAXN 205
int n,m,temp,ans;
int cap[205][205],flow[MAXN][MAXN];
int dis[MAXN];
int que[MAXN],pre[MAXN];
int min(int x,int y)
{
return x<y ? x : y;
}
int EK()
{
int i,temp;
int ans=0;
int head=0,tail=0;
memset(flow,0,sizeof(flow));
while(1)
{
memset(pre,0,sizeof(pre));
memset(dis,0,sizeof(dis));
dis[1]=INF;
que[tail]=1;
tail++;
pre[1]=1;
while(head != tail)
{
temp=que[head];
head++;
if(head == MAXN)
head=0;
for(i=1;i<=m;i++)
{
if(!dis[i] && flow[temp][i] < cap[temp][i])
{
dis[i] = min(dis[temp],cap[temp][i]-flow[temp][i]);
pre[i]=temp;
que[tail]=i;
tail++;
if(tail == MAXN)
tail=0;
}
}
}
if(dis[m] == 0)
break;
for(i=m;i!=1;i=pre[i])
{
flow[pre[i]][i] += dis[m];
flow[i][pre[i]] -= dis[m];
}
ans += dis[m];
}
return ans;
}
int main()
{
int i;
int si,ei,f;
while(scanf("%d%d",&n,&m)!=EOF)
{
ans=0;
memset(cap,0,sizeof(cap));
for(i=0;i<n;i++)
{
scanf("%d%d%d",&si,&ei,&f);
cap[si][ei] += f; //(处理重边,所以用加)
}
printf("%d\n",EK());
}
return 0;
}