EK算法解決POJ 1459
POJ 1459 http://poj.org/problem?id=1459
題意:
給幾個發(fā)電站,給幾個消耗站,再給幾個轉發(fā)點。
發(fā)電站只發(fā)電,消耗站只消耗電,轉發(fā)點只是轉發(fā)電,再給各個傳送線的傳電能力。
問你消耗站能獲得的最多電是多少。
//方法如下:
//虛擬出源點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聯(lián)系起來
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. 閱讀(405) 評論(0) 收藏 舉報
浙公網(wǎng)安備 33010602011771號