http://acm.pku.edu.cn/JudgeOnline/problem?id=1459
题目大意:建图后,有三个角色,power station,只产生不消耗能量,可以和源点相连,consumer,只消耗能量,可以和汇点相连,dispatcher,是调度员,起到中转站的作用。根据题了给的条件限制,就可以给每条边赋上一个容量。
算法分析:最大流。建图,增加一个源点和一个汇点,直接bfs(), 没有优化,很容易超时,至今还不会用sap和dinic,惭愧。
Ford_Fulkerson思想,EK解法,对EK也不太了解,有待努力。come on!
/* 无源无汇网络流 */
#include < string .h >
#include < queue >
#include < iostream >
using namespace std;
#define INF 0xfffffff
#define NN 110
int c[NN][NN]; // c[u][v] 表示边(u,v)的容量
int pre[NN];
int sourceNode, sinkNode;
int index[NN];
int list[NN][NN];
int bfs(){
int minf, i, cur, t, tmp;
queue < int > que;
que.push(sourceNode);
memset(pre, - 1 , sizeof (pre));
pre[sourceNode] = - 2 ;
minf = INF;
while ( ! que.empty()){
cur = que.front();
que.pop();
if (cur == sinkNode)
break ;
for (i = 0 ; i < index[cur]; i ++ ){
t = list[cur][i];
if (pre[t] == - 1 && c[cur][t] > 0 ){
que.push(t);
pre[t] = cur;
}
}
}
if (pre[sinkNode] == - 1 )
return - 1 ;
int next = sinkNode;
while (next != sourceNode){
tmp = pre[next];
if (c[tmp][next] < minf)
minf = c[tmp][next];
next = tmp;
}
return minf;
}
int Ford_Fulkerson()
{
int tmp, t, f, maxFlow;
maxFlow = 0 ;
while ((f = bfs()) != - 1 ){
maxFlow += f;
tmp = sinkNode;
while (pre[tmp] != - 2 ){
t = pre[tmp];
c[t][tmp] -= f;
c[tmp][t] += f;
tmp = t;
}
}
return maxFlow;
}
int main()
{
int n, np, nc, m, a, b, d;
while (scanf( " %d%d%d%d " , & n, & np, & nc, & m) != EOF){
memset(c, 0 , sizeof (c)); // 初始时将每个边赋予一个0容量
sourceNode = n; // 构造一个源点
sinkNode = n + 1 ; // 构造一个汇点
memset(index, 0 , sizeof (index));
while (m -- ){
scanf( " (%d,%d)%d " , & a, & b, & d);
if (c[a][b] + c[b][a] == 0 ){
list[a][index[a] ++ ] = b;
list[b][index[b] ++ ] = a;
}
c[a][b] += d;
}
while (np -- ){
scanf( " (%d)%d " , & a, & d);
list[sourceNode][index[sourceNode] ++ ] = a;
list[a][index[a] ++ ] = sourceNode;
c[sourceNode][a] += d; // produce能量,转化成从源到该能量站的边约束容量
}
while (nc -- ){
scanf( " (%d)%d " , & a, & d);
list[sinkNode][index[sinkNode] ++ ] = a;
list[a][index[a] ++ ] = sinkNode;
c[a][sinkNode] += d; // consumers所消费的能量,可看成从该consumers到汇点的边约束容量
}
printf( " %d\n " , Ford_Fulkerson());
}
return 0 ;
}
scanf(" (%d,%d)%d", &a, &b, &d);这种读入方式不错,前面的括号是字符,所以括号前的空格不能省去,否则读不进去。