1. 程式人生 > >ZOJ 2314 Reactor Cooling(無源匯上下界網絡流)

ZOJ 2314 Reactor Cooling(無源匯上下界網絡流)

vector namespace struct while ont reac 題意 coo pty

http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=2314

題意:

給出每條邊流量的上下界,問是否存在可行流,如果存在則輸出。

思路:
先定義D(u)為頂點u發出的所有弧的流量下界與進入頂點u的所有弧的流量下界和之差(out【u】-in【u】)。

對於無源匯的網絡流來說:

(1)新增兩個頂點S(附加源點)和T(附加匯點)。

(2)對原網絡中每個頂點u,計算出D(u),如果D(u)>0,則增加一條新弧<u,T>,這條弧的容量為D(u);如果D(u)<0,則增加一條新弧<S,u>,這條弧的容量為-D(u);如果D(u)=0,則不增加弧。

(3)原網絡中的每條弧的容量更改為c-b(上界-下界)。

跑一遍最大流,如果滿流,則存在可行流,每條邊的實際流量=每條邊的流量+該邊流量下界。

  1 #include<iostream>
  2 #include<algorithm>
  3 #include<cstring>
  4 #include<cstdio>
  5 #include<sstream>
  6 #include<vector>
  7 #include<stack>
  8 #include<queue>
  9
#include<cmath> 10 #include<map> 11 #include<set> 12 using namespace std; 13 typedef long long ll; 14 typedef pair<int,int> pll; 15 const int INF = 0x3f3f3f3f; 16 const int maxn = 50000 + 5; 17 18 int n, m; 19 20 int in[maxn]; 21 int out[maxn]; 22 int b[maxn];
23 24 struct Edge 25 { 26 int from,to,cap,flow; 27 Edge(int u,int v,int w,int f):from(u),to(v),cap(w),flow(f){} 28 }; 29 30 struct Dinic 31 { 32 int n,m,s,t; 33 vector<Edge> edges; 34 vector<int> G[maxn]; 35 bool vis[maxn]; 36 int cur[maxn]; 37 int d[maxn]; 38 39 void init(int n) 40 { 41 this->n=n; 42 for(int i=0;i<n;++i) G[i].clear(); 43 edges.clear(); 44 } 45 46 void AddEdge(int from,int to,int cap) 47 { 48 edges.push_back( Edge(from,to,cap,0) ); 49 edges.push_back( Edge(to,from,0,0) ); 50 m=edges.size(); 51 G[from].push_back(m-2); 52 G[to].push_back(m-1); 53 } 54 55 bool BFS() 56 { 57 queue<int> Q; 58 memset(vis,0,sizeof(vis)); 59 vis[s]=true; 60 d[s]=0; 61 Q.push(s); 62 while(!Q.empty()) 63 { 64 int x=Q.front(); Q.pop(); 65 for(int i=0;i<G[x].size();++i) 66 { 67 Edge& e=edges[G[x][i]]; 68 if(!vis[e.to] && e.cap>e.flow) 69 { 70 vis[e.to]=true; 71 d[e.to]=d[x]+1; 72 Q.push(e.to); 73 } 74 } 75 } 76 return vis[t]; 77 } 78 79 int DFS(int x,int a) 80 { 81 if(x==t || a==0) return a; 82 int flow=0, f; 83 for(int &i=cur[x];i<G[x].size();++i) 84 { 85 Edge &e=edges[G[x][i]]; 86 if(d[e.to]==d[x]+1 && (f=DFS(e.to,min(a,e.cap-e.flow) ) )>0) 87 { 88 e.flow +=f; 89 edges[G[x][i]^1].flow -=f; 90 flow +=f; 91 a -=f; 92 if(a==0) break; 93 } 94 } 95 return flow; 96 } 97 98 int Maxflow(int s,int t) 99 { 100 this->s=s; this->t=t; 101 int flow=0; 102 while(BFS()) 103 { 104 memset(cur,0,sizeof(cur)); 105 flow +=DFS(s,INF); 106 } 107 return flow; 108 } 109 110 void print(int num) 111 { 112 for(int i=0;i<num;i++) 113 { 114 printf("%d\n",edges[2*i].flow+b[i]); 115 } 116 } 117 }DC; 118 119 int main() 120 { 121 //freopen("in.txt","r",stdin); 122 int T; 123 scanf("%d",&T); 124 while(T--) 125 { 126 scanf("%d%d",&n, &m); 127 int src=0, dst=n+1; 128 DC.init(dst+1); 129 130 memset(in,0,sizeof(in)); 131 memset(out,0,sizeof(out)); 132 133 for(int i=0;i<m;i++) 134 { 135 int u, v, c; 136 scanf("%d%d%d%d",&u,&v,&b[i],&c); 137 DC.AddEdge(u,v,c-b[i]); 138 out[u]+=b[i]; 139 in[v]+=b[i]; 140 } 141 142 int flow=0; 143 for(int i=1;i<=n;i++) 144 { 145 if(out[i]<in[i]) 146 { 147 DC.AddEdge(src,i,in[i]-out[i]); 148 flow+=in[i]-out[i]; 149 } 150 else 151 { 152 DC.AddEdge(i,dst,out[i]-in[i]); 153 } 154 } 155 156 if(DC.Maxflow(src,dst)!=flow) {puts("NO");puts("");continue;} 157 158 puts("YES"); 159 DC.print(m); 160 puts(""); 161 } 162 return 0; 163 }

ZOJ 2314 Reactor Cooling(無源匯上下界網絡流)