题意:是说有一个水池,需要通过管道排水,给出管道数,给出两个管道间的最大流量,然后让你计算最多能拍多少水。
思路:是pku上的一道模板题,注意可能有重边的问题。
code:
//Edmonds-Karp算法,BFS找增广路
#include<cstdio>
#include<cstring>
#include<iostream>
#include<queue>
using namespace std;
const int INF = 1000000000;
const int MAXN = 205;
int n, m, s, t;
int a[MAXN], p[MAXN], cap[MAXN][MAXN], flow[MAXN][MAXN];
//上限容量cap,实际运送flow,从s到每个节点i的路径上最小残量a[i],则a[i]为整条路上最小残量
int main()
{
while(scanf("%d%d", &m, &n)!=EOF)
{
memset(cap, 0, sizeof(cap));
for(int i = 1; i <= m; i++)
{
int u, v, c;
scanf("%d%d%d", &u, &v, &c);
cap[u][v] += c; //注意重边
}
s = 1; //源点
t = n; //汇点
int ans = 0;
queue<int> q;
memset(flow, 0, sizeof(flow));
for(;;)
{
memset(a, 0, sizeof(a));
a[s] = INF;
q.push(s);
while(!q.empty()) //BFS找增广路
{
int u = q.front(); q.pop();
for(int v = 1; v <= n; v++) if(!a[v] && cap[u][v]>flow[u][v]) //找到新节点
{
p[v] = u; q.push(v); //记录v的父亲,加入FIFO队列
a[v] = a[u]<(cap[u][v] - flow[u][v])?a[u]:(cap[u][v] - flow[u][v]); //s-v路径上的最小残量
}
}
if(a[t] == 0) break; //找不到,则已经是最大值
for(int u = t; u != s; u = p[u]) //从汇点往回走
{
flow[p[u]][u] += a[t]; //更新正向流量
flow[u][p[u]] -= a[t]; //更新反向流量
}
ans += a[t]; //更新从s流出的总流量
}
printf("%d\n", ans);
}
return 0;
}