zoukankan      html  css  js  c++  java
  • sgu 176 上下界网络流最小可行流带输出方案

    算法步骤:

      1. 先将原图像最大可行流那样变换,唯一不同的是不加dst->src那条边来将它变成无源无汇的网络流图.直接跑一边超级源到超级汇的最大流.

      2. 加上刚才没有加上的那条边p

      3. 再跑一遍超级源汇之间的最大流,p的流量就是我们要求的最小可行流流量(等于其反向边的"容量")

    收获:

      1. 最大可行流和最小可行流,当我们把其残量网络求出来后,其流量就是dst->src的残量.

        每条边在此时的流量 = 流量下界 + 转换后对应边的流量

      1 #include <cstdio>
      2 #include <cassert>
      3 #include <cstring>
      4 #define min(a,b) ((a)<(b)?(a):(b))
      5 #define oo 0x3f3f3f3f
      6 #define N 110
      7 #define M N*N
      8 
      9 struct Dinic {
     10     int n, src, dst;
     11     int head[N], dest[M], flow[M], next[M], info[M], etot;
     12     int cur[N], dep[N], qu[N], bg, ed;
     13     void init( int n ) {
     14         this->n = n;
     15         memset( head, -1, sizeof(head) );
     16         etot = 0;
     17     }
     18     void adde( int i, int u, int v, int f ) {
     19         info[etot]=i, flow[etot]=f, dest[etot]=v, next[etot]=head[u]; head[u]=etot++;
     20         info[etot]=0, flow[etot]=0, dest[etot]=u, next[etot]=head[v]; head[v]=etot++;
     21     }
     22     bool bfs() {
     23         memset( dep, 0, sizeof(dep) );
     24         qu[bg=ed=1] = src;
     25         dep[src] = 1;
     26         while( bg<=ed ) {
     27             int u=qu[bg++];
     28             for( int t=head[u]; t!=-1; t=next[t] ) {
     29                 int v=dest[t], f=flow[t];
     30                 if( f && !dep[v] ) {
     31                     dep[v]=dep[u]+1;
     32                     qu[++ed] = v;
     33                 }
     34             }
     35         }
     36         return dep[dst];
     37     }
     38     int dfs( int u, int a ) {
     39         if( u==dst || a==0 ) return a;
     40         int remain=a, past=0, na;
     41         for( int &t=cur[u]; t!=-1; t=next[t] ) {
     42             int v=dest[t], &f=flow[t], &vf=flow[t^1];
     43             if( f && dep[v]==dep[u]+1 && (na=dfs(v,min(remain,f))) ) {
     44                 f -= na;
     45                 vf += na;
     46                 remain -= na;
     47                 past += na;
     48                 if( !remain ) break;
     49             }
     50         }
     51         return past;
     52     }
     53     int maxflow( int s, int t ) {
     54         int f = 0;
     55         src = s, dst = t;
     56         while( bfs() ) {
     57             memcpy( cur, head, sizeof(cur) );
     58             f += dfs(src,oo);
     59         }
     60         return f;
     61     }
     62 }dinic;
     63 struct Btop {
     64     int n;
     65     int head[N], dest[M], bval[M], tval[M], next[M], info[M], etot;
     66     int sumi[N], sumo[N];
     67     void init( int n ) {
     68         etot = 0;
     69         memset( head, -1, sizeof(head) );
     70         this->n = n;
     71     }
     72     void adde( int i, int u, int v, int b, int t ) {
     73         info[etot]=i, bval[etot]=b, tval[etot]=t;
     74         dest[etot]=v, next[etot]=head[u];
     75         sumi[v]+=b, sumo[u]+=b;
     76         head[u] = etot++;
     77     }
     78     int minflow( int src, int dst ) {
     79         int ss=n+1, tt=n+2, sum;
     80         dinic.init( n+2 );
     81         for( int u=1; u<=n; u++ )
     82             for( int t=head[u]; t!=-1; t=next[t] ) {
     83                 int v=dest[t];
     84                 dinic.adde( info[t], u, v, tval[t]-bval[t] );
     85             }
     86         sum = 0;
     87         for( int u=1; u<=n; u++ ) {
     88             if( sumi[u]>sumo[u] ) {
     89                 dinic.adde( 0, ss, u, sumi[u]-sumo[u] );
     90                 sum += sumi[u]-sumo[u];
     91             } else if( sumo[u]>sumi[u] ) {
     92                 dinic.adde( 0, u, tt, sumo[u]-sumi[u] );
     93             }
     94         }
     95         int f = 0;
     96         f += dinic.maxflow(ss,tt);
     97         dinic.adde( 0, dst, src, oo );
     98         f += dinic.maxflow(ss,tt);
     99         if( f!=sum ) return -1;
    100         int eid = dinic.etot-2;
    101         return dinic.flow[eid^1];
    102     }
    103 }btop;
    104 
    105 int n, m;
    106 int ans[M], tot;
    107 
    108 int main() {
    109     scanf( "%d%d", &n, &m );
    110     btop.init( n );
    111     for( int i=1,u,v,z,c; i<=m; i++ ) {
    112         scanf( "%d%d%d%d", &u, &v, &z, &c );
    113         if( c==1 ) btop.adde( i, u, v, z, z );
    114         else btop.adde( i, u, v, 0, z );
    115         ans[i] = c ? z : 0;
    116     }
    117     int minf = btop.minflow(1,n);
    118     if( minf==-1 ) {
    119         printf( "Impossible
    " );
    120         return 0;
    121     }
    122     for( int e=0; e<dinic.etot; e++ ) {
    123         int i=dinic.info[e];
    124         if( i ) ans[i] += dinic.flow[e^1];
    125     }
    126     printf( "%d
    ", minf );
    127     for( int i=1; i<=m; i++ )
    128         printf( "%d ", ans[i] );
    129     printf( "
    " );
    130 }
    View Code
  • 相关阅读:
    Java JVM启动参数
    使用Navicat连接MySQL8.0版本报1251错误
    安装MySQL和出现的问题解决
    跨域问题:解决跨域的三种方案
    Java8 新特性lambda表达式(一)初始
    搭建docker私有仓库
    crontab定时任务
    CentOS610 php环境安装
    Docker常用命令
    PHP调用python脚本执行时报错
  • 原文地址:https://www.cnblogs.com/idy002/p/4553014.html
Copyright © 2011-2022 走看看