ZOJ 2314 Reactor Cooling
2016-12-28 18:57
337 查看
题意:
n个点,m条水管,每条水管规定要从i到j有[L,R]的流量,
每个点流入流量和流出流量必须相等,构造出一种复合题意的解,或者证明无解
solution:
就是构造无源汇可行流啦,,建模方法如下
对每条[L,R]的边,从i到j连一条容量为R - L的边,对于每个点,
统计流入它的所有管道的下界流量和in[i],
类似地统计从它流出的下界流量和out[i],
定义du[i] = in[i] - out[i],
若du[i] > 0,说明该点要额外流出du[i]的流量,那么从S到i连一条容量为du[i]的边,
否则从i到T连一条容量为-du[i]的边
原图有可行流,当且仅当所有附加边满载(就是连接S,T的边),直接输出即可
n个点,m条水管,每条水管规定要从i到j有[L,R]的流量,
每个点流入流量和流出流量必须相等,构造出一种复合题意的解,或者证明无解
solution:
就是构造无源汇可行流啦,,建模方法如下
对每条[L,R]的边,从i到j连一条容量为R - L的边,对于每个点,
统计流入它的所有管道的下界流量和in[i],
类似地统计从它流出的下界流量和out[i],
定义du[i] = in[i] - out[i],
若du[i] > 0,说明该点要额外流出du[i]的流量,那么从S到i连一条容量为du[i]的边,
否则从i到T连一条容量为-du[i]的边
原图有可行流,当且仅当所有附加边满载(就是连接S,T的边),直接输出即可
#include<iostream> #include<cstring> #include<vector> #include<queue> #include<algorithm> #include<cmath> #include<cstdio> #include<bitset> using namespace std; const int maxn = 233; const int maxm = 2E5 + 20; const int INF = ~0U>>1; struct E{ int to,cap,flow,Num; E(){} E(int to,int cap,int flow,int Num): to(to),cap(cap),flow(flow),Num(Num){} }edgs[maxm]; int n,S,T,m,cnt,tot,Ans[maxm],in[maxn],out[maxn],cur[maxn],L[maxn]; vector <int> v[maxn]; queue <int> Q; void Add(int x,int y,int cap,int Num) { v[x].push_back(cnt); edgs[cnt++] = E(y,cap,0,Num); v[y].push_back(cnt); edgs[cnt++] = E(x,0,0,0); } int Dinic(int x,int a) { if (x == T) return a; int flow = 0; for (int &i = cur[x]; i < v[x].size(); i++) { E &e = edgs[v[x][i]]; if (e.cap == e.flow || L[e.to] != L[x] + 1) continue; int f = Dinic(e.to,min(a,e.cap - e.flow)); if (!f) continue; flow += f; e.flow += f; edgs[v[x][i]^1].flow -= f; a -= f; if (!a) return flow; } if (!flow) L[x] = -1; return flow; } bool BFS() { for (int i = S; i <= T; i++) L[i] = 0; L[S] = 1; Q.push(S); while (!Q.empty()) { int k = Q.front(); Q.pop(); for (int i = 0; i < v[k].size(); i++) { E e = edgs[v[k][i]]; if (e.cap == e.flow || L[e.to]) continue; L[e.to] = L[k] + 1; Q.push(e.to); } } return L[T]; } int main() { #ifdef DMC freopen("DMC.txt","r",stdin); #endif int cas; cin >> cas; while (cas--) { scanf("%d%d",&n,&m); T = n + 1; cnt = tot = 0; for (int i = 0; i <= n; i++) v[i].clear(),in[i] = out[i] = 0; for (int i = 1; i <= m; i++) { int x,y,l,c; scanf("%d%d%d%d",&x,&y,&l,&c); Add(x,y,c - l,i); Ans[i] = l; in[y] += l; out[x] += l; } for (int i = 1; i <= n; i++) { int du = in[i] - out[i]; if (du > 0) Add(S,i,du,0),tot += du; else if (du < 0) Add(i,T,-du,0); } int MaxFlow = 0; while (BFS()) { for (int i = S; i <= T; i++) cur[i] = 0; MaxFlow += Dinic(S,INF); } if (MaxFlow < tot) puts("NO"); else { puts("YES"); for (int i = 0; i < cnt; i++) if (edgs[i].Num) Ans[edgs[i].Num] += edgs[i].flow; for (int i = 1; i <= m; i++) printf("%d\n",Ans[i]); } puts(""); } return 0; }
相关文章推荐
- [zoj] 2314 Reactor Cooling || 无源汇上下界可行流
- zoj 2314 Reactor Cooling (有上下界的网络流)
- ZOJ 2314 Reactor Cooling
- ZOJ 2314 Reactor Cooling
- 【有上下界网络流】【ZOJ】2314 Reactor Cooling
- ZOJ_2314_Reactor Cooling_有上下界可行流模板
- zoj 2314 Reactor Cooling
- zoj 2314 Reactor Cooling
- ZOJ 2314 Reactor Cooling 上下界网络流(无源汇可行流)
- 【无源汇有上下界可行流】ZOJ-2314 Reactor Cooling
- ZOJ 2314 Reactor Cooling 无源汇上下界可行流
- ZOJ 2314 Reactor Cooling [无源汇上下界网络流]
- zoj 2314 Reactor Cooling (无源汇上下界可行流)
- zoj 2314 Reactor Cooling
- ZOJ 2314 Reactor Cooling 带上下界的网络流
- zoj 2314 Reactor Cooling 有上下界的网络最大流
- zoj 2314 Reactor Cooling 有上下界的网络最大流
- ZOJ 2314 Reactor Cooling 无源汇上下界网络流 可行流
- ZOJ 2314 Reactor Cooling 上下界网络流(无源汇可行流)
- zoj 2314 Reactor Cooling(无源汇上下界的可行流)