zoukankan      html  css  js  c++  java
  • sgu 194 无源汇的上下界可行流

    题目链接: http://acm.sgu.ru/problem.php?contest=0&problem=194

    题目大意:

      给定一个n个点,m条边的网络,每条边允许的流量范围< lij, cij >,问是否存在一个可行流可以在该网络内循环流动。

    分析:

      这是我做的第一个有上下界的可行流,这里的可行流应该指满足三个条件:

      1、流量平衡条件,2、容量限制条件即 lij <= fij <= cij; 3、反对称性: fij = -fji;

      思路是添加附加源和附件汇,一条边拆成三条边来构图达到容量限制的条件然后跑一遍最大流,参考自04年周源的国家集训队作业《一种简易的方法求解流量有上下界的网络中网络流问题》。

      代码我参考了: http://txhwind.diandian.com/post/2012-03-14/19643163

      最后还是证明EK模版是可以跑200个点的(事实上本来就可以),虽然DD在老博客里说他的超时了。

    代码:

    sgu194
      1 /*17.06.12 10:08    yimao     194    .CPP    Accepted    296 ms    1803 kb*/
      2 #include <cstdio>
      3 #include <cstring>
      4 #include <cmath>
      5 #include <iostream>
      6 #include <algorithm>
      7 #include <vector>
      8 using namespace std;
      9 
     10 #define mpair make_pair
     11 #define pii pair<int,int>
     12 #define MM(a,b) memset(a,b,sizeof(a));
     13 typedef long long lld;
     14 typedef unsigned long long u64;
     15 template<class T> bool up_max(T& a,const T& b){return b>a? a=b,1 : 0;}
     16 template<class T> bool up_min(T& a,const T& b){return b<a? a=b,1 : 0;}
     17 #define maxn 210
     18 const int inf= 2100000000;
     19 
     20 int n,m;
     21 int ST, ED;
     22 int g[maxn][maxn];
     23 pii e[maxn*maxn];
     24 int l[maxn][maxn], c[maxn][maxn];
     25 
     26 bool vis[maxn];
     27 int pre[maxn], que[maxn];
     28 bool bfs(){
     29     fill( vis, vis+2+n, 0 );
     30     int head= 0, tail= 0;
     31     que[tail++]= ST;
     32     vis[0]= ST;
     33     while( head<tail ){
     34         int u= que[head++];
     35         for(int v=1;v<=ED;++v){ /// ST==0;
     36             if( g[u][v]>0 && !vis[v] ){
     37                 pre[v]= u;
     38                 if( v==ED ) return 1;
     39                 que[tail++]= v;
     40                 vis[v]= 1;
     41             }
     42         }
     43     }
     44     return 0;
     45 }
     46 
     47 int Edmond_karp(){
     48     int ret= 0;
     49     ST= 0, ED= n+1;
     50     while( bfs() ){
     51         int t= inf;
     52         for(int i=ED;i!=ST;i=pre[i])
     53             up_min( t, g[pre[i]][i] );
     54         ret+= t;
     55         for(int i=ED;i!=ST;i=pre[i]){
     56             g[pre[i]][i]-= t;
     57             g[i][pre[i]]+= t;
     58         }
     59     }
     60     return ret;
     61 }
     62 
     63 int main()
     64 {
     65    //freopen("sgu194.in","r",stdin);
     66     while( cin>>n>>m ){
     67         for(int i=1;i<=n;++i)for(int j=1;j<=n;++j)l[i][j]= c[i][j]= 0;
     68         for(int i=0;i<=n+1;++i)for(int j=0;j<=n+1;++j)g[i][j]= 0;
     69 
     70         for(int i=1;i<=m;++i){
     71             int u,v,l1,l2;
     72             scanf("%d%d%d%d", &u, &v, &l1, &l2);
     73             e[i]= pii( u, v );
     74             l[u][v]= l1, c[u][v]= l2;
     75         }
     76 
     77         int sum= 0;
     78         for(int i=1;i<=n;++i){
     79             int t= 0;
     80             for(int j=1;j<=n;++j){
     81                 t+= l[j][i]-l[i][j];
     82                 g[i][j]= c[i][j]-l[i][j];
     83 
     84             }
     85             if( t>0 )
     86                 sum+= g[0][i]=t;
     87             else g[i][n+1]= -t;
     88         }
     89 
     90         int ret= Edmond_karp();
     91         if( ret<sum ) puts("NO");
     92         else{
     93             puts("YES");
     94             for(int i=1;i<=m;++i){
     95                 int x= e[i].first, y= e[i].second;
     96                 printf("%d\n", c[x][y]-g[x][y] );
     97             }
     98         }
     99     }
    100 }
    一毛原创作品,转载请注明出处。
  • 相关阅读:
    webpack安装、环境搭建和基本配置
    webpack知识点总结
    Vue之Vuex的使用
    vue之获取滚动条位置
    MongoDB ORM mongoose 配置和使用
    sequelize之通过options生成sql语句
    七牛上传之PutExtra的使用
    使用ssl-validator识别证书信息
    深入理解计算机系统(第三版)第八章重要内容摘要
    深入理解计算机系统(第三版)第七章重要内容摘要
  • 原文地址:https://www.cnblogs.com/yimao/p/2552595.html
Copyright © 2011-2022 走看看