标签:stdin color div min actor 流量 init target air
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(无源汇上下界网络流)
标签:stdin color div min actor 流量 init target air
原文地址:http://www.cnblogs.com/zyb993963526/p/7256832.html