POJ 1459 Power Network

解题思路:

首先添加两个节点,分别为起始点S,终点T,如果节点为power station,则添加一条S到当前节点的路径(路径容量为该节点的生产能力);如果节点为consumer,则添加当前节点到T的一条路径(路径容量为该节点的消费能力),则问题转化为求解S到T的最大流问题。

代码如下:

#include <iostream>
using namespace std;

#define INF 1e8
#define MAX_VECT 205
#define MAX_EDGE 22000

int to[MAX_EDGE], next[MAX_EDGE], cap[MAX_EDGE], m;
int v[MAX_VECT], d[MAX_VECT], queue[MAX_VECT], n;
int S, T;
inline
void single_insert(int _u, int _v, int var)
{
to[m]
= _v;
cap[m]
= var;
next[m]
= v[_u];
v[_u]
= m++;
}

void insert(int from, int to, int cap)
{
single_insert(from, to, cap);
single_insert(to, from,
0);
}

bool bfs_initial()
{
memset(d,
-1, sizeof(d));
int bg, ed, x, y;
bg
= ed = d[S] = 0;
queue[ed
++] = S;
while (bg < ed)
{
x
= queue[bg++];
for (int i = v[x]; i+1; i = next[i])
{
y
= to[i];
if (cap[i] && d[y] == -1)
{
d[y]
= d[x] + 1;
if (y == T) return true;
queue[ed
++] = y;
}
}
}
return false;
}


int dinic()
{
int ans = 0;
while(bfs_initial())
{
int edge, x, y, back, iter = 1;
while(iter)
{
x
= (iter == 1) ? S : to[queue[iter - 1]];
if (x == T)
{
int minE, minCap = INF;
for (int i = 1; i < iter; i++)
{
edge
= queue[i];
if (cap[edge] < minCap)
{
minCap
= cap[edge];
back
= i;
}
}
for (int i = 1; i < iter; i++)
{
edge
= queue[i];
cap[edge]
-= minCap;
cap[edge
^ 1] += minCap;
}
ans
+= minCap;
iter
= back;
}
else
{
for (edge = v[x]; edge + 1; edge = next[edge])
{
y
= to[edge];
if (cap[edge] && d[y] == d[x] + 1)
break;
}
if (edge+1)
queue[iter
++] = edge;
else
{
d[x]
= -1;
iter
--;
}
}
}
}
return ans;
};

int main()
{
int n, np, nc, _m, _u, _v, _c, ans;
while(scanf("%d%d%d%d", &n, &np, &nc, &_m)==4)
{
S
= n, T = n+1;
m
= ans = 0;
memset(v,
-1 ,sizeof(v));
while(_m--)
{
scanf(
"%*[^(](%d,%d)%d", &_u, &_v, &_c);
if (_u == _v)
continue;
insert(_u, _v, _c);
}
while (np--)
{
scanf(
"%*[^(](%d)%d", &_v, &_c);
insert(S, _v, _c);
}
while (nc--)
{
scanf(
"%*[^(](%d)%d", &_u, &_c);
insert(_u, T, _c);
}
printf(
"%d\n", dinic());
}

return 0;
}

 

posted on 2010-11-17 10:15  ltang  阅读(248)  评论(0编辑  收藏  举报

导航