题目链接:http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=11549
题意&思路:网络流的版题,基本照着小白书打的。
怎么实现增广路,通过正向和反向流量,不断寻找增广路(从起点开始,宽搜压入当前节点的下一节点,用书上术语即层次比当前节点大1的点,类似Dijkstra),当不存在到终点的增广路时,退出。
源码:
#include <cstdio>
#include <cmath>
#include <cstring>
#include <string>
#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
using namespace std;
int gmin(int a,int b){return a<b?a:b;}
int const inf = 1e8;
int const MAXN = 200+10;
int use[MAXN],c[MAXN][MAXN],flow[MAXN][MAXN],fa[MAXN],n,m;
void init()
{
memset(flow,0,sizeof(flow));
int i,j,s,e,val;
while(m--){
scanf("%d%d%d",&s,&e,&val);
flow[s-1][e-1] += val;
}
}
void solve()
{
int ans = 0;
int i,j,k;
int a[MAXN];
for(;;){
memset(use,0,sizeof(use));
memset(a,0,sizeof a);
queue<int>q;
q.push(0);
a[0] = inf;
fa[0] = 0; use[0] = 1;
while(!q.empty()){
int u = q.front(); q.pop();
for(i=0; i<n; i++){
if(use[i]==0 && flow[u][i]>0){
use[i] = 1;
fa[i] = u;
q.push(i);
a[i] = gmin(a[u],flow[u][i]);
}
}
}
if(a[n-1]==0)
break;
i = n-1;
while(i!=0){
flow[fa[i]][i] -= a[n-1];
flow[i][fa[i]] += a[n-1];
i = fa[i];
}
ans+=a[n-1];
}
printf("%d\n",ans);
}
int main()
{
while(scanf("%d%d",&m,&n)!=EOF){
init();
solve();
}
return 0;
}