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

 

你可能感兴趣的:(SSI)