zoukankan      html  css  js  c++  java
  • sgu 176 Flow construction(有源汇的上下界最小流)

    【题目链接】

        http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=11025

    【模型】

        有源汇点的上下界最小流。即既满足上下界又满足流量平衡的最小流量。

    【思路】

        按照可行流构造网络。不连t->s的边先跑一遍附加源汇点的最大流,然后连t->s一条inf边,在残量网络上跑一遍最大流。第一次求最大流所以能走的边都已经流满,第二次求附加源汇点最大流t->s的流量就会尽可能小。

        另外还可以二分下界mid,然后连边(T,S,mid),如果存在可行流则mid可行。

    【代码】

      1 #include<set>
      2 #include<cmath>
      3 #include<queue>
      4 #include<vector>
      5 #include<cstdio>
      6 #include<cstring>
      7 #include<iostream>
      8 #include<algorithm>
      9 #define trav(u,i) for(int i=front[u];i;i=e[i].nxt)
     10 #define FOR(a,b,c) for(int a=(b);a<=(c);a++)
     11 using namespace std;
     12 
     13 typedef long long ll;
     14 const int N = 5e4+10;
     15 const int inf = 1e9;
     16 
     17 ll read() {
     18     char c=getchar();
     19     ll f=1,x=0;
     20     while(!isdigit(c)) {
     21         if(c=='-') f=-1; c=getchar();
     22     }
     23     while(isdigit(c))
     24         x=x*10+c-'0',c=getchar();
     25     return x*f;
     26 }
     27 
     28 struct Edge {
     29     int u,v,cap,flow;
     30     Edge(int u=0,int v=0,int cap=0,int flow=0)
     31         :u(u),v(v),cap(cap),flow(flow){}
     32 };
     33 struct Dinic {
     34     int n,m,s,t;
     35     int d[N],cur[N],vis[N];
     36     vector<int> g[N];
     37     vector<Edge> es;
     38     queue<int> q;
     39     void init(int n) {
     40         this->n=n;
     41         es.clear();
     42         FOR(i,0,n) g[i].clear();
     43     }
     44     void clear() {
     45         FOR(i,0,(int)es.size()-1) es[i].flow=0;
     46     }
     47     void AddEdge(int u,int v,int w) {
     48         es.push_back(Edge(u,v,w,0));
     49         es.push_back(Edge(v,u,0,0));
     50         m=es.size();
     51         g[u].push_back(m-2);
     52         g[v].push_back(m-1);
     53     }
     54     int bfs() {
     55         memset(vis,0,sizeof(vis));
     56         q.push(s); d[s]=0; vis[s]=1;
     57         while(!q.empty()) {
     58             int u=q.front(); q.pop();
     59             FOR(i,0,(int)g[u].size()-1) {
     60                 Edge& e=es[g[u][i]];
     61                 int v=e.v;
     62                 if(!vis[v]&&e.cap>e.flow) {
     63                     vis[v]=1;
     64                     d[v]=d[u]+1;
     65                     q.push(v);
     66                 }
     67             }
     68         }
     69         return vis[t];
     70     }
     71     int dfs(int u,int a) {
     72         if(u==t||!a) return a;
     73         int flow=0,f;
     74         for(int& i=cur[u];i<g[u].size();i++) {
     75             Edge& e=es[g[u][i]];
     76             int v=e.v;
     77             if(d[v]==d[u]+1&&(f=dfs(v,min(a,e.cap-e.flow)))>0) {
     78                 e.flow+=f; 
     79                 es[g[u][i]^1].flow-=f;
     80                 flow+=f; a-=f;
     81                 if(!a) break;
     82             }
     83         }
     84         return flow;
     85     }
     86     int MaxFlow(int s,int t) {
     87         this->s=s,this->t=t;
     88         int flow=0;
     89         while(bfs()) {
     90             memset(cur,0,sizeof(cur));
     91             flow+=dfs(s,inf);
     92         }
     93         return flow;
     94     }
     95 } dc;
     96 
     97 int n,m,sum,down[N],in[N],id[N];
     98 
     99 int main()
    100 {
    101     while(scanf("%d%d",&n,&m)==2) {
    102         sum=0;
    103         int S=0,T=n+1;
    104         dc.init(T+2);
    105         memset(in,0,sizeof(in));
    106         FOR(i,1,m) {
    107             id[i]=-1;
    108             int x=read(),y=read(),z=read(),c=read();
    109             if(c) down[i]=z,sum+=z,dc.AddEdge(S,y,z),dc.AddEdge(x,T,z);
    110             else down[i]=0,dc.AddEdge(x,y,z),id[i]=dc.es.size()-2;
    111         }
    112         int flow=dc.MaxFlow(S,T);
    113         dc.AddEdge(n,1,inf);
    114         flow+=dc.MaxFlow(S,T);
    115         if(flow!=sum) puts("Impossible");
    116         else {
    117             printf("%d
    ",dc.es[dc.es.size()-2].flow);
    118             FOR(i,1,m-1) 
    119                 if(id[i]>=0) printf("%d ",dc.es[id[i]].flow+down[i]);
    120                 else printf("%d ",down[i]);
    121             if(id[m]>=0) printf("%d
    ",dc.es[id[m]].flow+down[m]);
    122             else printf("%d
    ",down[m]);
    123         }
    124     }
    125     return 0;
    126 }
  • 相关阅读:
    POJ 2236 Wireless Network(并查集)
    POJ 2010 Moo University
    POJ 3614 Sunscreen(贪心,区间单点匹配)
    POJ 2184 Cow Exhibition(背包)
    POJ 1631 Bridging signals(LIS的等价表述)
    POJ 3181 Dollar Dayz(递推,两个long long)
    POJ 3046 Ant Counting(递推,和号优化)
    POJ 3280 Cheapest Palindrome(区间dp)
    POJ 3616 Milking Time(dp)
    POJ 2385 Apple Catching(01背包)
  • 原文地址:https://www.cnblogs.com/lidaxin/p/5315698.html
Copyright © 2011-2022 走看看