有上下界限制可行流

无源汇有上下界限制可行流(循环流)

即每条边的流量限制为[L,R],判断有没有满足整个网络的可行流。

看看以前学的网络流,实际上它的流量限制为[0,C],现在无非多了一个下限的限制。

网络流的一个重要性质:除了源汇点的点,入流==出流。

本来点是不能存储水的,我们先不妨假设每条边都满足下限,对于某一条边来说,它的出水端的点水量-=L,入水端的点+=L,它的容量变为[0,R-L]。

这时候就会出现有的点水量是正的,另外点的水量是负的,如果能通过导流,使所有点的水量均为0,那么说明存在可行流。

怎么导流?建立一个超级源点s,超级汇点t,s向水量为正的点连边,容量即为水量。水量为负的点向t连边,容量即为水量。(自己脑补)

s到t跑一遍最大流,如果最大流为源点流出的水量之和,则存在可行流。。

有源汇的情况:汇点向源点连一条容量INF的边,即变成了无源汇的情况。

2018沈阳icpc网赛F(裸题):

  1 #include<iostream>
  2 #include<cstdio>
  3 #include<cstring>
  4 #include<vector>
  5 #include<algorithm>
  6 #include<queue>
  7 #include<map>
  8 using namespace std;
  9 typedef  long long ll;
 10 const int MAX_N = 5000;  
 11 const int MAX_M = 50000;  
 12 const int INF = 1000000000;  
 13 struct edge {
 14     int v, c, next;   
 15 } e[MAX_M];
 16 int p[MAX_N], eid;
 17 void init() {
 18     memset(p, -1, sizeof(p));
 19     eid = 0;
 20 }
 21 void insert(int u, int v, int c) {  
 22     e[eid].v = v;
 23     e[eid].c = c;
 24     e[eid].next = p[u];
 25     p[u] = eid++;
 26 }
 27 void addedge(int u, int v, int c) {  
 28     insert(u, v, c);
 29     insert(v, u, 0);  
 30 }
 31 int S, T;  
 32 int d[MAX_N];  
 33 bool CountLayer() {  
 34     memset(d, -1, sizeof(d));
 35     queue<int> q;
 36     q.push(S);
 37     d[S] = 0;
 38     while (!q.empty()) {
 39         int u = q.front();
 40         q.pop();
 41         for (int i = p[u]; i != -1; i = e[i].next) {
 42             int v = e[i].v;
 43             if (e[i].c > 0 && d[v] == -1) {
 44                 q.push(v);
 45                 d[v] = d[u] + 1;
 46             }
 47         }
 48     }
 49     return (d[T] != -1);  
 50 }
 51 
 52 ll dfs(int u, int flow) {  
 53     if (u == T) {
 54         return flow;
 55     }
 56     ll res = 0;
 57     for (int i = p[u]; i != -1; i = e[i].next) {
 58         int v = e[i].v;
 59         if (e[i].c > 0 && d[u] + 1 == d[v]) {
 60             ll tmp = dfs(v, min(flow, e[i].c));  
 61             flow -= tmp;
 62             e[i].c -= tmp;
 63             res += tmp;
 64             e[i ^ 1].c += tmp;  
 65             if (flow == 0) {  
 66                 break;
 67             }
 68         }
 69     }
 70     if (res == 0) {  
 71         d[u] = -1;
 72     }
 73     return res;
 74 }
 75 
 76 ll maxflow() {  
 77     ll res = 0;
 78     while (CountLayer()) {
 79         res += dfs(S, INF);  
 80     }
 81     return res;
 82 }
 83 ll def[5000];
 84 int main()
 85 {   
 86     int d=1; 
 87     int n,m,k;
 88     while(cin>>n>>m>>k)
 89     {
 90         int l,r,u,v;
 91         S=n+m+3,T=n+m+4;
 92         init();
 93         memset(def,0,sizeof def);
 94         scanf("%d%d",&l,&r);
 95         for(int i=1;i<=k;i++)
 96         {
 97             scanf("%d%d",&u,&v);
 98             v=v+n;
 99             addedge(u, v, 1);
100         }
101         for(int i=1;i<=n;i++)
102         {
103             addedge(n+m+1, i, r-l);
104             def[i]+=l;
105         }
106         for(int i=n+1;i<=n+m;i++)
107         {
108             addedge(i, n+m+2, r-l);
109             def[i]-=l;
110         }
111         addedge(n+m+2,n+m+1,INF);
112        
113         ll sum=0;
114         for(int i=1;i<=n+m;i++)
115         {
116             if(def[i]>0) {addedge(S,i,def[i]);sum+=def[i];}
117             else addedge(i,T,-def[i]);
118         }
119         if(sum==maxflow()) printf("Case %d: Yes\n",d++);
120         else printf("Case %d: No\n",d++);
121     }
122     return 0;
123 }

 

posted @ 2018-09-19 19:14  hzhuan  阅读(156)  评论(0编辑  收藏  举报