坐井观天

In the name of dream

导航

POJ 1637 网络流构图

Posted on 2012-06-11 23:02  一毛_  阅读(204)  评论(0)    收藏  举报

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

题目大意:

 

分析:

http://blog.163.com/zhoumhan_0351/blog/static/39954227200982051154725/

http://blog.csdn.net/niushuai666/article/details/6917777

http://www.cppblog.com/koson/archive/2007/12/21/39243.html

对于上面的建图,可以作如下改进法:对于每一条无向边e(i),涉及点j和点k, 则可以建立一条容量大小为1的边从v(j)流向v(k),从源点向v(j)添加一条容量为1的边。可以证明,改进的建图跟上面的前五步建图方法建立的图是等效的,但省略了e(i)更为简洁高效。

 

代码:

poj1637
  1 /*1637    Accepted    376K    63MS    C++    2353B    2012-06-11 22:26:29*/
  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 in[maxn], out[maxn], un[maxn];
 23 int g[maxn][maxn];
 24 
 25 bool vis[maxn];
 26 int que[maxn], pre[maxn];
 27 bool bfs(){
 28     MM( vis, 0 );
 29     int head= 0, tail= 0;
 30     que[tail++]= ST;
 31     vis[ST]= 1;
 32     while( head<tail ){
 33         int u= que[head++];
 34         for(int v=1;v<=ED;++v){
 35             if( g[u][v] && !vis[v] ){
 36                 pre[v]= u;
 37                 if( v==ED ) return 1;
 38                 que[tail++]= v;
 39                 vis[v]= 1;
 40             }
 41         }
 42     }
 43     return 0;
 44 }
 45 
 46 int Edmonds_karp(){
 47     int ret= 0;
 48     while( bfs() ){
 49         int t= inf;
 50         for(int i=ED;i!=ST;i= pre[i])
 51             up_min( t, g[pre[i]][i] );
 52         ret+= t;
 53         for(int i=ED;i!=ST;i= pre[i]){
 54             g[ pre[i] ][i]-= t;
 55             g[i][ pre[i] ]+= t;
 56         }
 57     }
 58     return ret;
 59 }
 60 
 61 int main()
 62 {
 63     // freopen("poj1637.in","r",stdin);
 64     int T;
 65     cin>>T;
 66     while( T-- ){
 67         cin>>n>>m;
 68         int i,j,x,y,t;
 69         MM( g, 0 );
 70         ST= 0, ED= n+1;
 71         for(i=ST;i<=ED;++i) in[i]= out[i]= un[i]= 0;
 72         while( m-- ){
 73             scanf("%d%d%d", &x, &y, &t);
 74             if( 1==t ){
 75                 ++out[x];
 76                 ++in[y];
 77             }
 78             else{
 79                 ++un[x];
 80                 ++un[y];
 81                 ++g[ST][x]; ///
 82                 ++g[x][y]; ///
 83             }
 84         }
 85         bool ok= 1;
 86         int sum= 0;
 87         for(i=1;i<=n;++i){
 88             int tot= in[i]+out[i]+un[i];
 89             if( tot&1 || in[i] > out[i] + un[i] || out[i] > in[i] + un[i] ){
 90                     ok=0; break;
 91             }
 92             g[i][ED]+= tot / 2 - in[i];
 93             sum+= tot/2 - in[i];
 94         }
 95         if( sum != Edmonds_karp() ) ok= 0;
 96 
 97         if( !ok ) puts("impossible");
 98         else puts("possible");
 99     }
100 }