采用先分层,再用DFS找增广路的的方法。O(n^2m)
#include <iostream>
#include <queue>
using namespace std;
#define min(a,b) (a<b?a:b)
#define MAXN 105
const int inf = 0x7fffffff;
struct {
int flow;
int capacity;
} map[MAXN][MAXN];
int n, np, nc, m; //n节点总数,np发电站数,nc消费者数,m边数
int maxflow, sp, fp; //最大流,源点,汇点
int depth[MAXN]; // 用于dinic分层
bool bfs() //分层
{
memset(depth, 0, sizeof(depth));
int u;
queue<int> q;
q.push(sp);
depth[sp] = 1;
while (!q.empty()) {
u = q.front(); q.pop();
for (int v = 1; v <= n; ++v) {
if (!depth[v] && map[u][v].capacity > map[u][v].flow) {
q.push(v);
depth[v] = depth[u] + 1;
}
}
if (u == fp)
return true;
}
return false;
}
int dfs(int cur, int sum)
{
if (cur == fp)
return sum;
int s = sum, ret;
for (int v = 1; v <= n; ++v) { //只跟上下层有关,牛
if (depth[v] == depth[cur]+1 && s && map[cur][v].capacity > map[cur][v].flow) {
ret = dfs(v, min(map[cur][v].capacity - map[cur][v].flow, s));
map[cur][v].flow += ret;
map[v][cur].flow -= ret;
s -= ret;
}
}
return sum - s;
}
void dinic()
{
maxflow = 0;
while (bfs())
maxflow += dfs(sp, inf);
}
int main()
{
//freopen("temp.txt", "r", stdin);
int x, y, z;
char tmp;
while (cin >> n >> np >> nc >> m) {
memset(map, 0, sizeof(map));
for (int i = 1; i <= m; ++i) {
cin >> tmp >> x >> tmp >> y >> tmp >> z;
map[x+1][y+1].capacity = z;
}
//新建源点指向所有的发电站
sp = n+1;
fp = n+2;
n += 2;
for (int i = 1; i <= np; ++i) {
cin >> tmp >> x >> tmp >> y;
map[sp][x+1].capacity = y;
}
//新建汇点,使所有消费者指向它
for (int i = 1; i <= nc; ++i) {
cin >> tmp >> x >> tmp >> y;
map[x+1][fp].capacity = y;
}
dinic();
cout << maxflow << endl;
}
return 0;
}