uva 10330(最大流)

题意:一张网络中有若干个源点及汇点。点上又最大能承载的流量超过了则会自动丢弃,让你求最大流。

思路:稍微转化一下套一下模版就ok了。ps:刚刚入门网络流0.0只会模版。

这里就讲一下图的转化吧。首先由于在每一点上都有限制所以我们必须把一个点拆成两个点,在两个点当中加一条边,来实现对于点上流量的控制。另外由于是有多个源点+多个汇点。所以我们要认为的加上一个源点使得此点到所有源点都有一条流量为无穷大的边,再人为加一个汇点,使得所有汇点到这一点都有一条流量为无穷大的边。这样一来图就建好了,剩下来的就是套模版了。

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <cstdlib>
 5 #include <algorithm>
 6 #include <utility>
 7 #include <vector>
 8 #include <queue>
 9 #include <stack>
10 #define INF 500001
11 #define LEN 510
12 
13 using namespace std;
14 
15 int cap[LEN][LEN], n;
16 
17 void debug()
18 {
19     for(int i=0; i<n; i++){
20         for(int j=0; j<n; j++){
21             cout << cap[i][j] << ' ';
22         }cout << endl;
23     }cout << endl;
24 }
25 
26 int EK(int s, int t)
27 {
28     int f, flow[LEN][LEN], a[LEN], p[LEN];
29     queue<int> q;
30     memset(flow, 0, sizeof flow);
31     f = 0;
32     while(1){
33         memset(a, 0, sizeof a);
34         a[s] = INF;
35         q.push(s);
36         while(!q.empty()){
37             int u = q.front(); q.pop();
38             for(int v=0; v<n; v++){
39                 if(!a[v] && cap[u][v]>flow[u][v]){
40                     p[v] = u;
41                     q.push(v);
42                     a[v] = min(a[u], cap[u][v]-flow[u][v]);
43                 }
44             }
45         }
46         if(a[t] == 0)break;
47         for(int u=t; u!=s; u = p[u]){
48             flow[p[u]][u]+=a[t];
49             flow[u][p[u]]-=a[t];
50         }
51         f+=a[t];
52     }
53     return f;
54 }
55 
56 int main()
57 {
58 //    freopen("in.txt", "r", stdin);
59 
60     int vn, vl, m;
61     while(scanf("%d", &vn)!=EOF){
62         memset(cap, 0, sizeof cap);
63         n = 2*vn+2;
64         for(int i=1; i<=vn; i++){
65             scanf("%d", &vl);
66             cap[i<<1][(i<<1)|1] = vl;
67             cap[(i<<1)|1][i<<1] = vl;
68         }
69         scanf("%d", &m);
70         for(int i=0; i<m; i++){
71             int a, b, val;
72             scanf("%d%d%d", &a, &b, &val);
73             cap[(a<<1)|1][b<<1] = val;
74         }
75 //        debug();
76         int ns, ne;
77         scanf("%d%d", &ns, &ne);
78         for(int i=0; i<ns; i++){
79             int v;
80             scanf("%d", &v);
81             cap[0][v<<1] = cap[v<<1][(v<<1)|1];
82         }
83         for(int i=0; i<ne; i++){
84             int v;
85             scanf("%d", &v);
86             cap[(v<<1)|1][1] = cap[v<<1][(v<<1)|1];
87         }
88         int ans;
89         ans = EK(0,1);
90         printf("%d
", ans);
91     }
92     return 0;
93 }
View Code
奔跑吧!少年!趁着你还年轻
原文地址:https://www.cnblogs.com/shu-xiaohao/p/3470380.html