• bzoj 2406 二分+有源有汇上下界网络流可行流判定


    弱爆了,典型的行列建模方式,居然想不到,题做少了,总结少了。。。。。。

    二分答案mid

    s----------------------->i行----------------------->j列----------------------------->t

         [si-mid,si+mid]                  [L,R]                 [s[j]-mid,s[j]+mid]

    即对每一行建一个点,每一列建一个点,用边来表示某一行某一列上的东西.

    这种建模方式一般要整体考虑行或列的某些信息.

      1  /**************************************************************
      2     Problem: 2406
      3     User: idy002
      4     Language: C++
      5     Result: Accepted
      6     Time:396 ms
      7     Memory:4576 kb
      8 ****************************************************************/
      9  
     10 #include <cstdio>
     11 #include <cstring>
     12 #define min(a,b) ((a)<(b)?(a):(b))
     13 #define oo 0x3f3f3f3f
     14 #define N 510
     15 #define S 100010
     16  
     17 struct Dinic {
     18     int n, src, dst;
     19     int head[N], dest[S], flow[S], next[S], etot;
     20     int dep[N], cur[N], qu[N], bg, ed;
     21  
     22     void init( int n, int src, int dst ) {
     23         memset( head, -1, sizeof(head) );
     24         etot = 0;
     25         this->n = n;
     26         this->src = src;
     27         this->dst = dst;
     28     }
     29     void adde( int u, int v, int f ) {
     30 //      fprintf( stderr, "Dinic::adde( %d %d %d )
    ", u, v, f );
     31         next[etot]=head[u]; flow[etot]=f; dest[etot]=v; head[u]=etot++;
     32         next[etot]=head[v]; flow[etot]=0; dest[etot]=u; head[v]=etot++;
     33     }
     34     bool bfs() {
     35         memset( dep, 0, sizeof(dep) );
     36         qu[bg=ed=1] = src;
     37         dep[src] = 1;
     38         while( bg<=ed ) {
     39             int u=qu[bg++];
     40             for( int t=head[u]; ~t; t=next[t] ) {
     41                 int v=dest[t], f=flow[t];
     42                 if( f && !dep[v] ) {
     43                     dep[v] = dep[u]+1;
     44                     qu[++ed] = v;
     45                 }
     46             }
     47         }
     48         return dep[dst];
     49     }
     50     int dfs( int u, int a ) {
     51         if( u==dst || a==0 ) return a;
     52         int remain=a, past=0, na;
     53         for( int &t=cur[u]; ~t; t=next[t] ) {
     54             int v=dest[t], &f=flow[t], &vf=flow[t^1];
     55             if( f && dep[v]==dep[u]+1 && (na=dfs(v,min(remain,f))) ) {
     56                 f -= na;
     57                 vf += na;
     58                 remain -= na;
     59                 past += na;
     60                 if( !remain ) break;
     61             }
     62         }
     63         return past;
     64     }
     65     int maxflow() {
     66         int f = 0;
     67         while( bfs() ) {
     68             for( int u=1; u<=n; u++ ) cur[u]=head[u];
     69             f += dfs( src, oo );
     70         }
     71 //      fprintf( stderr, "maxflow() = %d
    ", f );
     72         return f;
     73     }
     74 };
     75 struct TopBot {
     76     int n;
     77     int head[N], dest[S], top[S], bot[S], next[S], etot;
     78     int sin[N], sout[N];
     79     Dinic D;
     80     void init( int n ) {
     81         this->n = n;
     82         etot = 0;
     83         memset( head, 0, sizeof(head) );
     84         memset( sin, 0, sizeof(sin) );
     85         memset( sout, 0, sizeof(sout) );
     86     }
     87     void adde( int u, int v, int t, int b ) {
     88 //      fprintf( stderr, "TopBot::adde( %d %d [%d,%d] )
    ", u, v, b, t );
     89         etot++;
     90         dest[etot] = v;
     91         top[etot] = t;
     92         bot[etot] = b;
     93         next[etot] = head[u];
     94         head[u] = etot;
     95         sin[v] += b;
     96         sout[u] += b;
     97     }
     98     bool ok() {
     99         int src=n+1, dst=n+2;
    100         D.init( n+2, src, dst );
    101         for( int u=1; u<=n; u++ )
    102             for( int t=head[u]; t; t=next[t] ) {
    103                 int v=dest[t];
    104                 D.adde( u, v, top[t]-bot[t] );
    105             }
    106         int sumf = 0;
    107         for( int u=1; u<=n; u++ ) {
    108             if( sin[u]>sout[u] ) 
    109                 D.adde( src, u, sin[u]-sout[u] );
    110             else if( sin[u]<sout[u] ) {
    111                 D.adde( u, dst, sout[u]-sin[u] );
    112                 sumf += sout[u]-sin[u];
    113             }
    114         }
    115 //      fprintf( stderr, "sumf=%d
    ", sumf );
    116         return D.maxflow()==sumf;
    117     }
    118 }T;
    119  
    120 int n, m;
    121 int w[N][N], L, R;
    122 int s[2][N];
    123  
    124 bool ok( int mid ) {
    125     int src = n+m+1, dst = n+m+2;
    126     int st=0, sb=0;
    127     T.init(dst);
    128     for( int i=1; i<=n; i++ ) {
    129         int t=s[0][i]+mid, b=s[0][i]-mid;
    130         b = b<0 ? 0 : b;
    131         T.adde( src, i, t, b );
    132         st += t;
    133         sb += b;
    134     }
    135     for( int i=1; i<=n; i++ )
    136         for( int j=1; j<=m; j++ )
    137             T.adde( i, n+j, R, L );
    138     for( int i=1; i<=m; i++ ) {
    139         int t=s[1][i]+mid, b=s[1][i]-mid;
    140         b = b<0 ? 0 : b;
    141         T.adde( n+i, dst, t, b );
    142     }
    143     T.adde( dst, src, st, sb );
    144     return T.ok();
    145 }
    146 int main() {
    147     scanf( "%d%d", &n, &m );
    148     for( int i=1; i<=n; i++ )
    149         for( int j=1; j<=m; j++ ) {
    150             scanf( "%d", &w[i][j] );
    151             s[0][i] += w[i][j];
    152             s[1][j] += w[i][j];
    153         }
    154     scanf( "%d%d", &L, &R );
    155     int lf=0, rg=200000;
    156     while( lf<rg ) {
    157         int mid=lf+((rg-lf)>>1);
    158         if( ok(mid) ) rg=mid;
    159         else lf=mid+1;
    160     }
    161     printf( "%d
    ", lf );
    162 }
    View Code
  • 相关阅读:
    nyoj 228士兵杀敌(五)
    hdu2072 单词数
    nyoj123士兵杀敌(四)(树状数组)
    nyoj1092数字分隔(二)
    HDU1166:敌兵布阵(线段树单点更新,区间查询)
    nyoj269VF(dp)
    nyoj 860又见01背包(01背包)
    poj2184(01背包变形)
    HDU2159FATE(完全背包变形)
    HDU4508 完全背包
  • 原文地址:https://www.cnblogs.com/idy002/p/4550153.html
Copyright © 2020-2023  润新知