SGU 194 Reactor Cooling 有上下界的网络流 网络流拆点

前端之家收集整理的这篇文章主要介绍了SGU 194 Reactor Cooling 有上下界的网络流 网络流拆点前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

无源汇有上下界限制网络流

拆点可解

设超级源点 ss 和超级汇点 tt

deg[i] = i 点的流入容量和 - i 点的流出容量和

若 deg[i] > 0 建立 ss -> i 边权为 deg[i] 的边 强行流出 deg[i] 的流量

若 deg[i] < 0 建立 i -> tt 边权为 -deg[i] 的边 强行流入 -deg[i] 的流量

代码(AC,15ms

  1. #include<iostream>
  2. #include<queue>
  3. #include<cstdlib>
  4. #include<vector>
  5. #include<cstring>
  6. #include<cstdio>
  7. using namespace std;
  8. const int INF = 0x7ffffff;
  9. const int MAXN = 205;
  10. const int MAXM = MAXN * MAXN;
  11. int n,m,s,t,cnt;
  12. bool vis[MAXN];
  13. int head[MAXN],deg[MAXM],dl[MAXM];
  14. int d[MAXN],cur[MAXN],que[MAXN];
  15. struct edge_{
  16. int from,to,cap,flow,next;
  17. }edge[MAXM];
  18.  
  19. void init(){
  20. memset(head,-1,sizeof(head));
  21. memset(edge,sizeof(edge));
  22. memset(deg,sizeof(deg));
  23. cnt = 0;
  24. }
  25.  
  26. void add(int from,int to,int cap){
  27. edge[cnt].from = from,edge[cnt].to = to;
  28. edge[cnt].cap = cap,edge[cnt].next = head[from];
  29. edge[cnt].flow = 0;
  30. head[from] = cnt++;
  31. edge[cnt].from = to,edge[cnt].to = from;
  32. edge[cnt].cap = 0,edge[cnt].next = head[to];
  33. edge[cnt].flow = 0;
  34. head[to] = cnt++;
  35. }
  36.  
  37. bool bfs(){
  38. memset(vis,false,sizeof(vis));
  39. memset(d,sizeof(d));
  40. d[s] = 0,vis[s] = 1,que[0] = s;
  41. int tail = 0,front = 1;
  42. while(tail < front){
  43. int x = que[tail++];
  44. for(int now = head[x]; ~now; now = edge[now].next){
  45. edge_ &e = edge[now];
  46. if(!vis[e.to] && e.cap > e.flow){
  47. vis[e.to] = 1;
  48. d[e.to] = d[x] + 1;
  49. que[front++] = e.to;
  50. }
  51. }
  52. }
  53. return vis[t];
  54. }
  55.  
  56. int dfs(int x,int a){
  57. if(x == t || a == 0)
  58. return a;
  59. int flow = 0,f;
  60. for(int &now = cur[x]; ~now; now = edge[now].next){
  61. edge_ &e = edge[now];
  62. if(d[x] + 1 == d[e.to] && (f = dfs(e.to,min(a,e.cap - e.flow))) > 0){
  63. e.flow +=f;
  64. edge[now ^ 1].flow -= f;
  65. flow += f;
  66. a -= f;
  67. if(a == 0)
  68. break;
  69. }
  70. }
  71. return flow;
  72. }
  73.  
  74. int maxFlow(int _s,int _t,int _n,int _m){
  75. s = _s,t = _t;
  76. n = _n,m = _m;
  77. int flow = 0;
  78. while(bfs()){
  79. for(int i = 1; i <= n; i++)
  80. cur[i] = head[i];
  81. flow += dfs(s,INF);
  82. }
  83. return flow;
  84. }
  85.  
  86. int main(){
  87. int n,l,r,ss,tt;
  88. while(~scanf("%d%d",&n,&m)){
  89. init();
  90. ss = n + 1,tt = n + 2;
  91. for(int i = 1; i <= m; ++i){
  92. scanf("%d%d%d%d",&s,&t,&l,&r);
  93. deg[s] -= l,deg[t] += l,dl[i] = l;
  94. add(s,r - l);
  95. }
  96. int sum = 0;
  97. for(int i = 1; i <= n; ++i){
  98. if(deg[i] > 0){
  99. add(ss,i,deg[i]);
  100. sum += deg[i];
  101. }
  102. else
  103. add(i,tt,-deg[i]);
  104. }
  105. if(maxFlow(ss,n + 2,m) == sum){
  106. printf("YES\n");
  107. for(int i = 0; i < m; ++i)
  108. printf("%d\n",edge[i * 2].flow + dl[i + 1]);
  109. }
  110. else{
  111. printf("NO\n");
  112. }
  113. }
  114. return 0;
  115. }

猜你在找的React相关文章