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;
}