zoukankan      html  css  js  c++  java
  • 有上下界限制可行流

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

    即每条边的流量限制为[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
    ",d++);
    120         else printf("Case %d: No
    ",d++);
    121     }
    122     return 0;
    123 }
  • 相关阅读:
    poj1220(短除法实现任意进制转换)
    poj1061(扩展欧基里德定理)
    快速乘+快速幂(用于模数超过int范围)
    poj3761(反序表)
    Educational Codeforces Round 64 -C(二分)
    牛客小白月赛13-H(单调栈+树状数组)
    poj3321(dfs序+树状数组)
    Codeforces Round #598 (Div. 3)E(dp路径转移)
    记忆化dp博弈
    2-sat
  • 原文地址:https://www.cnblogs.com/lnu161403214/p/9676465.html
Copyright © 2011-2022 走看看