UVa 10330 - Power Transmission(最大流--拆点)

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 }
View Code

 

posted @ 2013-07-16 20:49  發_  阅读(674)  评论(0编辑  收藏  举报