#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <algorithm>
#include <queue>
using std::queue;
#define Max 65535
int V, V_Source, V_End, E;
int SuperSource, SuperEnd, level;
int h[103], e[103];
int list[103][103], f[103][103], Map[103][103];
void bfs()
{
bool visit[103];
queue<int> queue_vertex;
int x;
memset(h, 0, sizeof(h));
memset(visit, false, sizeof(visit));
queue_vertex.push(SuperEnd);
visit[SuperEnd] = true;
while (!queue_vertex.empty())
{
x = queue_vertex.front();
queue_vertex.pop();
for (int i = 0; i < V; ++i)
if (!visit[i] && Map[i][x] > 0)
{
queue_vertex.push(i);
visit[i]=true;
h[i] = h[x] + 1;
}
}
h[SuperSource] = V - 1;
}
void init()
{
char str[101];
memset(f, 0, sizeof(f));
memset(e, 0, sizeof(e));
memset(Map, 0, sizeof(Map));
memset(list, 0, sizeof(list));
SuperSource = V++;
SuperEnd = V++;
for (int i = 0, x, y, z; i < E; Map[x][y] = z, ++i)
scanf("%d %d %d", &x, &y, &z);
for (int i = 0, x, z; i < V_Source; Map[SuperSource][x] = z, ++i)
scanf("%d %d", &x, &z);
for (int i = 0, x, z; i < V_End; Map[x][SuperEnd] = z, ++i)
scanf("%d %d", &x, &z);
bfs();
for (int i = 0; i < V; ++i)
if (Map[SuperSource][i] > 0)
{
e[SuperSource] -= Map[SuperSource][i];
e[i] += Map[SuperSource][i];
f[SuperSource][i] += Map[SuperSource][i];
f[i][SuperSource] = -f[SuperSource][i];
}
for (int i = 0, j = V - 2, x; i < j; ++i)
if (e[i] > 0)
{
++list[h[i]][0];
x = list[h[i]][0];
list[h[i]][x] = i;
}
}
void push(int u, int v)
{
int tem = std::min(e[u], Map[u][v] - f[u][v]), x;
if (e[v] == 0 && v != SuperSource && v != SuperEnd)
{
++list[h[v]][0];
x = list[h[v]][0];
list[h[v]][x] = v;
if (h[v] > level)
level = h[v];
}
e[u] -= tem;
e[v] += tem;
f[u][v] += tem;
f[v][u] = -f[u][v];
}
void relabel(int v)
{
int mh = Max;
for (int i = 0; i < V; ++i)
if (i != v && h[i] >= h[v] && Map[v][i] - f[v][i] > 0)
mh = std::min(mh, h[i]);
h[v] = mh + 1;
level = h[v];
++list[level][0];
list[level][1] = v;
}
void work()
{
int v, tem, flag;
level = 0;
for (int i = 0, j = V - 2; i < j; ++i)
if (e[i] > 0)
level = std::max(level, h[i]);
while (level)
{
tem = list[level][0];
v = list[level][tem];
--list[level][0];
while (level > 0 && list[level][0] == 0)
--level;
flag = false;
for (int i = 0; i < V; ++i)
{
if (e[v] == 0)
break;
if (h[i] + 1 == h[v] && Map[v][i] - f[v][i] > 0)
{
push(v, i);
flag = true;
}
}
if (!flag || e[v] > 0)
relabel(v);
}
}
int main()
{
while (scanf("%d %d %d %d", &V, &V_Source, &V_End, &E)!= EOF)
{
init();
work();
printf("%d\n", e[SuperEnd]);
}
return 0;
}
额...原题里面说有一堆出发点, 一堆接收点, 一堆中转站, 还是标准方法: 建立超级原点和超级汇点, 然后执行即可.
嗯...用的是最高标号预留推进算法, 算是网络流里面比较快速的算法了, 复杂度是n*n*√m, 还是相当迅速的
参照了图论书上的代码写了写...但是感觉还是不太好