http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=1271
题目:普通的网络流模型加多了一个每个节点的流量限制。
刚开始的时候是直接找增广路,顺便更新节点的容量,但是证明不了其正确性,WA了,大概这种做法是错的。
正解:将每个点拆成两个点,并且这两个点构成的边的容量是该点容量,这样就保证流过的流量不大于该点容量。
1 /* 2 *Author: Zhaofa Fang 3 *Created time: 2013-07-16-20.00 4 *Language: C++ 5 */ 6 #include <cstdio> 7 #include <cstdlib> 8 #include <sstream> 9 #include <iostream> 10 #include <cmath> 11 #include <cstring> 12 #include <algorithm> 13 #include <string> 14 #include <utility> 15 #include <vector> 16 #include <queue> 17 #include <map> 18 #include <set> 19 using namespace std; 20 21 typedef long long ll; 22 #define DEBUG(x) cout<< #x << ':' << x << endl 23 #define FOR(i,s,t) for(int i = (s);i <= (t);i++) 24 #define FORD(i,s,t) for(int i = (s);i >= (t);i--) 25 #define REP(i,n) for(int i=0;i<(n);i++) 26 #define REPD(i,n) for(int i=(n-1);i>=0;i--) 27 #define PII pair<int,int> 28 #define PB push_back 29 #define MP make_pair 30 #define ft first 31 #define sd second 32 #define lowbit(x) (x&(-x)) 33 #define INF (1<<30) 34 #define eps 1e-8 35 36 const int maxn = 220; 37 const int maxm = 40011; 38 struct Edge{ 39 int v,cap,flow,next; 40 }edge[maxm]; 41 int eh[maxn],tot; 42 bool vist[maxn]; 43 int d[maxn]; 44 45 void init(){ 46 tot = 0; 47 memset(eh,-1,sizeof(eh)); 48 } 49 void addedge(int u,int v,int c){ 50 Edge e = {v,c,0,eh[u]}; 51 edge[tot] = e; 52 eh[u] = tot ++; 53 } 54 void add(int u,int v,int c){ 55 addedge(u,v,c); 56 addedge(v,u,0); 57 } 58 bool BFS(int s,int t){ 59 memset(vist,0,sizeof(vist)); 60 queue<int>Q; 61 Q.push(s); 62 vist[s] = 1; 63 d[s] = 0; 64 while(!Q.empty()){ 65 int u = Q.front(); 66 Q.pop(); 67 for(int i=eh[u];i!=-1;i=edge[i].next){ 68 int v = edge[i].v; 69 if(!vist[v] && edge[i].cap > edge[i].flow){ 70 vist[v] = 1; 71 d[v] = d[u] + 1; 72 Q.push(v); 73 if(v == t)return true; 74 } 75 } 76 } 77 return false; 78 } 79 int DFS(int u,int t,int avi){ 80 if(u == t || avi == 0)return avi; 81 int flow = 0 ,f; 82 for(int i=eh[u];i!=-1;i=edge[i].next){ 83 int v = edge[i].v; 84 if(d[v] == d[u]+1 && (f=DFS(v,t,min(avi,edge[i].cap-edge[i].flow)))>0){ 85 edge[i].flow += f; 86 edge[i^1].flow -= f; 87 flow += f; 88 avi -= f; 89 if(avi == 0)break; 90 } 91 } 92 return flow; 93 } 94 int maxFlow(int s,int t){ 95 int flow = 0; 96 while(BFS(s,t)){ 97 flow += DFS(s,t,INF); 98 } 99 return flow; 100 } 101 int main(){ 102 //freopen("in","r",stdin); 103 //freopen("out","w",stdout); 104 int n; 105 while(~scanf("%d",&n)){ 106 int u,v,c,m; 107 init(); 108 REP(i,n){ 109 scanf("%d",&c); 110 add(i+1,n+i+1,c); 111 } 112 scanf("%d",&m); 113 while(m--){ 114 scanf("%d%d%d",&u,&v,&c); 115 add(n+u,v,c); 116 } 117 int B,D; 118 scanf("%d%d",&B,&D); 119 while(B--){ 120 scanf("%d",&u); 121 add(0,u,INF); 122 } 123 while(D--){ 124 scanf("%d",&u); 125 add(n+u,2*n+1,INF); 126 } 127 printf("%d\n",maxFlow(0,2*n+1)); 128 } 129 return 0; 130 }