回顾网络流,学得最好的应该就是最大流了,都已经忘得差不多了。这道题还是很基础的题目啊,原来做过又做了一次。
代码:
#include<iostream>
using namespace std;
#define INF 0x7fffffff
#define maxn 205
struct Edge
{
int v,w,next;
} e[maxn*2];
int head[maxn],pre[maxn];
int que[maxn],cur[maxn],size;
bool mark[maxn];
void AddEdge(int a,int b,int c)
{
e[size].v=b;
e[size].w=c;
e[size].next=head[a];
head[a]=size++;
}
int EK(int s,int t)
{
int first,rear,u,v,i,ret;
ret=0;
while( true){
first=rear=0;
memset(mark,false,sizeof(mark));
memset(cur,-1,sizeof(-1));
memset(pre,-1,sizeof(pre));
que[rear++]=s;
mark[s]=true;
while( first!=rear&&!mark[t]){
u=que[first++];
for( i=head[u]; i!=-1&&!mark[t]; i=e[i].next){
v=e[i].v;
if( !mark[v]&&e[i].w>0){
pre[v]=u;
cur[v]=i;
mark[v]=true;
que[rear++]=v;
}
}
}
if(!mark[t]) break;
int mimf=INF; //寻找增广路径上的最小流量
for( i=t; i!=s; i=pre[i])
mimf=min(mimf,e[cur[i]].w);
ret+=mimf;
for( i=t; i!=s; i=pre[i]){ //正边减上最小流量,反边加上最小流量
e[cur[i]].w-=mimf;
e[cur[i]^1].w+=mimf;
}
}
return ret;
}
int main()
{
int n,m,a,c,b;
while( scanf("%d%d",&m,&n)!=EOF){
size=0;
memset(e,0,sizeof(e));
memset(head,-1,sizeof(head));
while( m--){
scanf("%d%d%d",&a,&b,&c);
AddEdge(a,b,c);
AddEdge(b,a,0);
}
printf("%d\n",EK(1,n));
}
return 0;
}