码迷,mamicode.com
首页 > 其他好文 > 详细

ZOJ 2314 Reactor Cooling 无源汇有上下界网络流

时间:2015-10-07 15:55:15      阅读:179      评论:0      收藏:0      [点我收藏+]

标签:

题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=1314

题意:给出N个点,M条边的有向图,每条边的有上下界规定,问是否存在一个可行流满足条件,如果满足输出YES并输出每条边的流量。

如果不满足输出NO。

 

根据周源的《一种简易的方法求解流量有上下界的网络中网络流问题

无源汇上下界网络流的做法是:

设边u->v的下界是B(u,v),上界是C(u,v)。

设M(i)为对于i结点的流入i的下界总和-流出i的下界总和。

增设源点s和汇点t。

如果M(i)>=0 连边s->i,容量为M(i)。

如果M(i)<0 连边i->t,容量为-M(i)。

对于图中的原来的边u-v,连边u->v,容量为C(u,v)-B(u,v)。

然后求最大流。如果对于源点出发的所有边都满流,则说明存在一个可行流满足条件。

 

  1 #include <bits/stdc++.h>
  2 using namespace std;
  3 int N, M;
  4 #define maxn 210
  5 const int inf = 0x3f3f3f3f;
  6 struct Edge
  7 {
  8     int from, to, cap, flow;
  9     Edge(int f, int t, int c, int fl)
 10     {
 11         from = f; to = t; cap = c; flow = fl;
 12     }
 13 };
 14 vector <Edge> edges;
 15 vector <int> G[maxn];
 16 int cur[maxn], vis[maxn], d[maxn];
 17 int n, m, s, t;
 18 void AddEdge(int from, int to, int cap)
 19 {
 20     edges.push_back(Edge(from, to, cap, 0));
 21     edges.push_back(Edge(to, from, 0, 0));
 22     m = edges.size();
 23     G[from].push_back(m-2);
 24     G[to].push_back(m-1);
 25 }
 26 bool bfs()
 27 {
 28     memset(vis, 0, sizeof(vis));
 29     vis[s] = 1;
 30     d[s] = 0;
 31     queue <int> q;
 32     q.push(s);
 33     while(!q.empty())
 34     {
 35         int u = q.front(); q.pop();
 36         for(int i = 0; i < G[u].size(); i++)
 37         {
 38             Edge &e = edges[G[u][i]];
 39             if(!vis[e.to] && e.cap > e.flow)
 40             {
 41                 vis[e.to] = 1;
 42                 d[e.to] = d[u]+1;
 43                 q.push(e.to);
 44             }
 45         }
 46     }
 47     return vis[t];
 48 }
 49 int dfs(int x, int a)
 50 {
 51     if(x == t || a == 0) return a;
 52     int flow = 0, f;
 53     for(int &i = cur[x]; i < G[x].size(); i++)
 54     {
 55         Edge &e = edges[G[x][i]];
 56         if(d[x]+1 == d[e.to] && (f = dfs(e.to, min(e.cap - e.flow, a))) > 0)
 57         {
 58             e.flow += f;
 59             edges[G[x][i]^1].flow -= f;
 60             flow += f;
 61             a -= f;
 62             if(a == 0) break;
 63         }
 64     }
 65     return flow;
 66 }
 67 int MaxFlow()
 68 {
 69     int flow = 0;
 70     while(bfs())
 71     {
 72         memset(cur, 0, sizeof(cur));
 73         flow += dfs(s, inf);
 74     }
 75     return flow;
 76 }
 77 int T;
 78 int in[maxn], out[maxn], Mi[maxn];
 79 int low[210*210];
 80 int main()
 81 {
 82     scanf("%d", &T);
 83     while(T--)
 84     {
 85         edges.clear();
 86         for(int i = s; i <= t; i++) G[i].clear();
 87         scanf("%d%d", &N, &M);
 88         s = 0; t = N+1;
 89         memset(in, 0, sizeof(in));
 90         memset(out, 0, sizeof(out));
 91         for(int i = 1; i <= M; i++)
 92         {
 93             int u, v, l, f;
 94             scanf("%d%d%d%d", &u, &v, &l, &f);
 95             low[i] = l;
 96             AddEdge(u, v, f-l);
 97             out[u] += l;
 98             in[v] += l;
 99         }
100         for(int i = 1; i <= N; i++)
101         {
102             Mi[i] = in[i] - out[i];
103             if(Mi[i] >= 0) AddEdge(s, i, Mi[i]);
104             else AddEdge(i, t, -Mi[i]);
105         }
106         int flow = MaxFlow();
107         vector <int> ans;
108         bool flag = true;
109         for(int i = 0; i < m; i+=2)
110         {
111             if(edges[i].from == s && edges[i].cap > edges[i].flow)
112             {
113                 flag = false; break;
114             }
115             else if(edges[i].from != s && edges[i].to != t)
116             {
117                 ans.push_back(edges[i].flow);
118             }
119         }
120         if(flag)
121         {
122             printf("YES\n");
123             for(int i = 0; i < ans.size(); i++)
124             {
125                 printf("%d\n", ans[i]+low[i+1]);
126             }
127         }
128         else printf("NO\n");
129     }
130     return 0;
131 }

 

ZOJ 2314 Reactor Cooling 无源汇有上下界网络流

标签:

原文地址:http://www.cnblogs.com/titicia/p/4858680.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!