http://poj.org/problem?id=1273
最大流算法:
一张图有一个源点一个汇点,中间有很多要经过的点,点与点之间有最大流量的限制,问从源点到汇点的最大每秒流量是多少
加入了残余网络和增广路这两个概念
残余网络:是对于一次处理之后得到得剩下的图
增广路:对于u到i的的流量我少了x容量那么i到u我反向多个x容量,保证能够反悔不走这条路
EK算法复杂度O(VM) V:最大容量 M:边数
具体证明:http://www.cnblogs.com/luweiseu/archive/2012/07/14/2591573.html java代码看的头晕~~
代码实现:
/************************************************
* Author :Powatr
* Created Time :2015-8-24 19:40:52
* File Name :POJ1273_EK.cpp
************************************************/
#include <cstdio>
#include <algorithm>
#include <iostream>
#include <sstream>
#include <cstring>
#include <cmath>
#include <string>
#include <vector>
#include <queue>
#include <deque>
#include <stack>
#include <list>
#include <map>
#include <set>
#include <bitset>
#include <cstdlib>
#include <ctime>
using namespace std;
#define lson l, mid, rt << 1
#define rson mid + 1, r, rt << 1 | 1
typedef long long ll;
const int MAXN = 2e2 + 10;
const int INF = 0x3f3f3f3f;
const int MOD = 1e9 + 7;
int pre[MAXN];
int n, m, ans;
int mp[MAXN][MAXN];
queue<int> q;
void EK()
{
while(1){
memset(pre, 0, sizeof(pre));
while(!q.empty()) q.pop();
q.push(1);
while(!q.empty()){
int now = q.front(); q.pop();
if(now == m) break;
for(int i = 1; i <= m; i++){
if(mp[now][i] > 0 && !pre[i]){
pre[i] = now;
q.push(i);
}
}
}
if(pre[m] == 0) break;
int min1 = INF;
for(int i = m; i != 1; i = pre[i])
min1 = min(min1, mp[pre[i]][i]);
for(int i = m; i != 1 ; i = pre[i]){
mp[pre[i]][i] -= min1;
mp[i][pre[i]] += min1;
}
ans += min1;
}
}
int main(){
while(~scanf("%d%d", &n, &m)){
ans = 0;
memset(mp, 0, sizeof(mp));
int u, v, val;
for(int i = 1; i <= n; i++){
scanf("%d%d%d", &u, &v, &val);
mp[u][v] += val;
}
EK();
printf("%d\n", ans);
}
return 0;
}