http://poj.org/problem?id=1459
网络流之最大流问题处女作,使用的是Edmonds-Karp算法。此外,这又是一道玩转输入的神题,使用sscanf解析字符串内容。
像本题这种多源多汇的最大流问题,只需建立一个超级源点S和一个超级汇点T即可。S连接所有发电站,T连接所有用户。
AC代码:
#include <queue>
#include <stdio.h>
#include <string.h>
#include <iostream>
#include <algorithm>
using namespace std;
const int MAX = 110;
const int INT_MAX = 0x3f3f3f3f;
int map[MAX][MAX],pre[MAX];
int n,np,nc,m;
char ss[30];
queue <int> Q;
bool BFS(int src, int des){///宽搜寻找增广路径
memset(pre, -1, sizeof(pre));
while(!Q.empty()) Q.pop();
pre[src] = 0;
int index;
Q.push(src);
while(!Q.empty()){
index = Q.front();
Q.pop();
for(int i=0; i<=1+n; i++){
if(pre[i] == -1 && map[index][i] > 0){
pre[i] = index;
if(i == des) return true;
Q.push(i);
}
}
}
return false;
}
int EK(int src, int des){
int maxflow = 0;
while(BFS(src, des)){
int minflow = INT_MAX;
for(int i=des; i!=src; i=pre[i])
minflow = min(minflow, map[pre[i]][i]);
for(int i=des; i!=src; i=pre[i]){
map[pre[i]][i] -= minflow;
map[i][pre[i]] += minflow;
}
maxflow += minflow;
}
return maxflow;
}
int main(){
while(scanf("%d%d%d%d",&n,&np,&nc,&m) == 4){
memset(map, 0, sizeof(map));
int src = n, des = n + 1;
int u, v, w;
for(int i=0; i<m; i++){
scanf("%s",ss);
sscanf(ss, "(%d,%d)%d",&u,&v,&w);
map[u][v] = w;
}
for(int i=0; i<np; i++){
scanf("%s",ss);
sscanf(ss,"(%d)%d",&v,&w);
map[src][v] = w;
}
for(int i=0; i<nc; i++){
scanf("%s",ss);
sscanf(ss,"(%d)%d",&u,&w);
map[u][des] = w;
}
printf("%d\n",EK(src, des));
}
return 0;
}