第一道网络流的题目,我是看这个讲解的http://www.nocow.cn/index.php/%E7%BD%91%E7%BB%9C%E6%B5%81Edmonds-Karp 算法
主要是顶点有值限制,所以可以将一个点分成两个点a和a',它们两个之间的容量就是顶点的值
代码如下:
1 #include <cstdio> 2 #include <cstring> 3 #include <queue> 4 using namespace std; 5 6 const int maxn = 300; 7 const int inf = 0x7fffffff; 8 int g[maxn][maxn]; 9 int pre[maxn]; 10 int n,m; 11 12 int maxflow(int end) 13 { 14 int ans = 0; 15 while(true) 16 { 17 queue<int> q; 18 q.push(0); 19 memset(pre,-1,sizeof(pre)); 20 while(!q.empty()) 21 { 22 int u = q.front(); 23 q.pop(); 24 for(int v = 1;v <= end&&pre[end] < 0;v ++) 25 { 26 if(g[u][v] > 0 && pre[v] == -1) 27 { 28 pre[v] = u; 29 q.push(v); 30 } 31 if(pre[end] >= 0) 32 break; 33 } 34 } 35 if(pre[end] < 0) 36 break; 37 int min = -1; 38 for(int v = end;v > 0;v = pre[v]) 39 { 40 if(min == -1 || min > g[pre[v]][v]) 41 min = g[pre[v]][v]; 42 } 43 int v; 44 for(int t = pre[v = end];t >= 0;v = t,t = pre[v]) 45 { 46 g[t][v] -= min; 47 g[v][t] += min; 48 } 49 ans += min; 50 51 } 52 53 return ans; 54 } 55 56 int main() 57 { 58 while(scanf("%d",&n) == 1) 59 { 60 memset(g,0,sizeof(g)); 61 int a,b,c; 62 for(int i = 1;i <= n;i ++) 63 { 64 scanf("%d",&a); 65 g[i][i+n] = a; 66 } 67 scanf("%d",&m); 68 for(int i = 0;i < m;i ++) 69 { 70 scanf("%d%d%d",&a,&b,&c); 71 g[a+n][b] = c; 72 } 73 int B,D; 74 scanf("%d%d",&B,&D); 75 for(int i = 0;i < B;i ++) 76 { 77 scanf("%d",&a); 78 g[0][a] = inf; 79 } 80 81 for(int i = 0;i < D;i ++) 82 { 83 scanf("%d",&a); 84 g[a+n][2*n + 1] = inf; 85 } 86 87 printf("%d\n",maxflow(2*n+1)); 88 } 89 90 return 0; 91 }