最近一直在写数论。。。。上课无聊学了一下网络流。。先刷一下这个水题吧。。。刚开始写了一个1s++效率非常低。。。只好借鉴被人的程序了。。。。。网络流第一次写。。。感觉这个算法很好的。。。
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int map1[105][105], lev[105];
int que[300], iq;
bool bfs(int s, int t) {
int u, k, i;
memset(lev, 0, sizeof (lev));
iq = 0, lev[s] = 1;
que[iq++] = s;
for (i = 0; i < iq; i++) {
u = que[i];
if (u == t) return 1;
for (k = 0; k <= t; k++)
if (map1[u][k] > 0 && !lev[k]) {
lev[k] = lev[u] + 1, que[iq++] = k;
}
}
return 0;
}
int dinic(int s, int t) {
int a[105], cur[105], pre[105];
int Mflow = 0, i, u, k, f, v;
while (bfs(s, t)) {
for (i = 0; i <= t; i++) // 初始化,回溯的时候找到cur,初始为0
cur[i] = 0, a[i] = INT_MAX; //a里是剩余流量
u = s;
while (1) {
for (v = cur[u]; v <= t; v++)
if (map1[u][v] > 0 && lev[v] == lev[u] + 1)
break;
if (v <= t) {
cur[u] = v + 1, pre[v] = u, a[v] = map1[u][v];
if (a[v] > a[u])
a[v] = a[u];
u = v;
if (u == t) {
f = a[t];
Mflow += f;
for (v = t; v != s; v = pre[v]) {
cur[pre[v]] = v;
map1[pre[v]][v] -= f, map1[v][pre[v]] += f;
a[v] -= f;
if (map1[pre[v]][v] == 0)
u = pre[v];
}
}
} else {
if (u != s)
lev[u] = INT_MAX, u = pre[u];
else
break;
}
}
}
return Mflow;
}
int main() {
int n, np, nc, m, i, j, u, v, w;
while (scanf("%d%d%d%d", &n, &np, &nc, &m) != -1) {
memset(map1, 0, sizeof (map1));
for (i = 1; i <= m; i++) {
scanf(" (%d,%d)%d", &u, &v, &w);
map1[u][v] = w;
}
for (i = 1; i <= np; i++) {
scanf(" (%d)%d", &u, &w);
map1[n][u] = w;
}
for (i = 1; i <= nc; i++) {
scanf(" (%d)%d", &u, &w);
map1[u][n + 1] = w;
}
printf("%d\n", dinic(n, n + 1));
}
return 0;
}