书山有径勤为路>>>>>>>>

<<<<<<<<学海无涯苦作舟!

EK算法解决POJ 1459

POJ 1459 http://poj.org/problem?id=1459

题意:

给几个发电站,给几个消耗站,再给几个转发点。
发电站只发电,消耗站只消耗电,转发点只是转发电,再给各个传送线的传电能力。
问你消耗站能获得的最多电是多少。

//方法如下: 
//虚拟出源点0和汇点n+1; 将所有的源点与0相连,将所有的汇点和n+1相连
#include <iostream>
#include <cstring>
using namespace std;
const int inf = 100000000;
const int maxN = 105;
int n, np, nc, m, l[maxN][maxN], s, t;
int q[maxN], maxFlow, pre[maxN];
void addFlow()
{
int minL = inf, cur = t; //t是目标点, cur是当前的点
while(cur != s) //s是源点,只要没有到达源点
{
if(l[pre[cur]][cur] < minL)
minL = l[pre[cur]][cur];
cur = pre[cur];
}
cur = t;
while(cur != s)
{
l[pre[cur]][cur] -= minL;
l[cur][pre[cur]] += minL;
cur = pre[cur];
}
maxFlow += minL; //最大流相加
}
void fulk()//BFS
{
while(true)
{
memset(pre, -1, sizeof(pre)); //将每个pre初始化为-1
int head = 0, tail = 0, cur;
q[tail++] = s; //将源点0放入队列中
while(head != tail)
{
cur = q[head++]; //取出
for(int j=0; j<=n+1; j++)
{
if(l[cur][j] != 0 && pre[j] == -1) //cur到j可达,并且pre没有被用过
{
pre[j] = cur; //用pre将cur与j联系起来
q[tail++] = j; //将j放入队列
}
}
if(pre[t] != -1) break; //到了目标点
}
if(pre[t] != -1) addFlow(); //到了目标点,开始增广
else break; //要不然退出
}
}

int main()
{
while(cin >> n)
{
cin >> np >> nc >> m;
memset(l, 0, sizeof(l)); //每条边都初始化为0
s = 0, t = n + 1, maxFlow = 0;
char tmp;
int u, v, z;
for(int i=1; i<=m; i++)
{
cin >> tmp >> u >> tmp >> v >> tmp >> z;
l[u+1][v+1] = z;
}
for(int i=1; i<=np; i++)
{
cin >> tmp >> u >> tmp >> z;
l[s][u+1] = z; //将源点和0相连
}
for(int i=1; i<=nc; i++)
{
cin >> tmp >> u >> tmp >> z;
l[u+1][t] = z; //将汇点与n+1相连
}
fulk();
cout << maxFlow << endl;
}
return 0;
}



posted on 2011-11-18 22:07  More study needed.  阅读(394)  评论(0编辑  收藏  举报

导航

书山有径勤为路>>>>>>>>

<<<<<<<<学海无涯苦作舟!