zoukankan      html  css  js  c++  java
  • POJ 2396 有源汇的上下界可行流(好题)

    (P.S.   POJ终于300题了,弱菜啊!!!)

    题目链接: http://poj.org/problem?id=2396

    题目大意:

      给定一个矩阵每行,每列的和,和各个元素的限制条件(>, =, <),求出一个满足这各种限制的矩阵。 

    分析;

      我做了前面两道sgu的入门题,发现看这题的解题报告就很好懂了,其实原理方面我还是没有lin神那么理解得透彻。

      http://hi.baidu.com/zfy0701/blog/item/6449d82a64e15e3e5343c1ba.html

      http://blog.csdn.net/water_glass/article/details/6823741

    注意:

      1、源S,汇T, 附加源ST(X), 附加汇ED(Y),将有源汇的转换为无源汇的应该是在添加了附加源汇之后再连一条T->S的容量为无穷大的边。

      2、这题我错了一天啊,究其原因非常神奇把input数据的处理随便改改就神奇地过了,也就是当输入x  y  =  t 时候,判断是否有错误的代码应该是:

        if( x>c[u][v] || x<l[u][v] ) Flag= 0;就足够了,而我自己多加了一句话就wa到底了(具体见下面的代码吧),这不是说明即使一个题你会算法,可以说什么都会照样有你在某在状态下ac不了的题么?

    代码:

    poj2396
      1 /*2396    Accepted    924K    141MS    C++    3650B    2012-06-18 21:53:56*/
      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 240
     18 const int inf= 2100000000;
     19 
     20 int n,m,N;
     21 int ST, ED;
     22 int g[maxn][maxn];
     23 int c[maxn][maxn], l[maxn][maxn];
     24 
     25 bool Flag;
     26 
     27 void change(int u,int v,char ch,int x){
     28     if( '=' == ch ){
     29         /// if( c[u][v]==l[u][v] ) Flag= 0;  // if have this code, it gets Wrong Answer!!!
     30         if( x>c[u][v] || x<l[u][v] ) Flag= 0;
     31         c[u][v]= l[u][v]= x;
     32     }
     33     else if( '<' == ch ){
     34         up_min( c[u][v], x-1 );
     35         if( c[u][v] < l[u][v] ) Flag= 0;
     36     }
     37     else if( '>' == ch ){
     38         up_max( l[u][v], x+1 );
     39         if( c[u][v] < l[u][v] ) Flag= 0;
     40     }
     41 }
     42 
     43 void Read(){
     44     char ch;
     45     int i,j,u,v,x,t;
     46     cin>>n>>m;
     47     N= n+m+1;
     48     MM( c, 0 );
     49     MM( l, 0 );
     50     for(i=1;i<=n;++i){
     51         scanf("%d", &t);
     52         c[0][i]= l[0][i]= t;
     53     }
     54     for(i=1;i<=m;++i){
     55         scanf("%d", &t);
     56         c[i+n][N]= l[i+n][N]= t;
     57     }
     58     for(i=1;i<=n;++i)for(j=1;j<=m;++j){ c[i][j+n]= inf; l[i][j+n]= 0; }
     59     cin>>t;
     60     while( t-- ){
     61         scanf("%d %d %c %d", &u, &v, &ch, &x );
     62         if( 0==u && 0==v ){
     63             for(i=1;i<=n;++i) for(j=1;j<=m;++j) change( i, j+n, ch, x );
     64         }
     65         else if( 0==u ){
     66             for(i=1;i<=n;++i) change( i, v+n, ch, x );
     67         }
     68         else if( 0==v ){
     69             for(i=1;i<=m;++i) change( u, i+n, ch, x );
     70         }
     71         else change( u, v+n, ch, x );
     72     }
     73 }
     74 
     75 int build_graph(){
     76     int sum= 0;
     77     ST= N+1, ED= N+2;
     78     MM( g, 0 );
     79     for(int i=0;i<=N;++i){
     80         int t= 0;
     81         for(int j=0;j<=N;++j){
     82             t+= l[j][i]-l[i][j];
     83             g[i][j]= c[i][j]-l[i][j];
     84         }
     85         if(t>0) sum+= g[ST][i]= t; /// t>0!!!;
     86         else g[i][ED]= -t;
     87     }
     88     g[N][0]= inf; ///!!!
     89     return sum;
     90 }
     91 
     92 bool vis[maxn];
     93 int que[maxn], pre[maxn];
     94 bool bfs(){
     95     MM( vis, 0 );
     96     int head=0, tail=0;
     97     que[tail++]= ST;
     98     vis[ST]= 1;
     99     while( head<tail ){
    100         int u= que[head++];
    101         for(int v=0;v<=ED;++v){
    102             if( g[u][v]>0 && !vis[v] ){
    103                 pre[v]= u;
    104                 if( v==ED ) return 1;
    105                 que[tail++]= v;
    106                 vis[v]= 1;
    107             }
    108         }
    109     }
    110     return 0;
    111 }
    112 
    113 int Edmond_karp(){
    114     int ret= 0;
    115     while( bfs() ){
    116         int t= inf;
    117         for(int i=ED;i!=ST;i=pre[i])
    118             up_min( t, g[pre[i]][i] );
    119         ret+= t;
    120         for(int i=ED;i!=ST;i=pre[i]){
    121             g[pre[i]][i]-= t;
    122             g[i][pre[i]]+= t;
    123         }
    124     }
    125     return ret;
    126 }
    127 
    128 int main()
    129 {
    130     //freopen("poj2396.in","r",stdin);
    131     int Cas;
    132     cin>>Cas;
    133     while( Cas-- ){
    134         Flag= 1;
    135         Read();
    136         if( !Flag ){
    137             puts("IMPOSSIBLE");
    138             if( Cas>0 ) puts("");
    139             continue;
    140         }
    141 
    142         int sum= build_graph();
    143         int ret= Edmond_karp();
    144         if( ret<sum ) puts("IMPOSSIBLE");
    145         else{
    146             for(int i=1;i<=n;++i)
    147                 for(int j=1;j<=m;++j)
    148                     //printf("%d%c", c[i][j+n]-g[i][j+n], j==m ? '\n' : ' ' );
    149                     printf("%d%c", g[j+n][i]+l[i][j+n], j==m ? '\n' : ' ' );
    150         }
    151         if( Cas>0 ) puts("");
    152     }
    153 }
    一毛原创作品,转载请注明出处。
  • 相关阅读:
    文件合并
    排序
    canvas 的cliprect()实现画布剪切DEMO
    SurfaceViewDemo
    View实现事件监听DEMO(文本跟随触屏事件)
    android progressBar和seekBar的小DEMO
    Android DrawerLayoutDemo
    Fragment和FragmentActivity使用Demo
    SharedPreferences DEMO
    android中sharedPreferences的用法
  • 原文地址:https://www.cnblogs.com/yimao/p/2554067.html
Copyright © 2011-2022 走看看