坐井观天

In the name of dream

导航

POJ 1459 构图+最大流(Edmond_karp模版)

Posted on 2012-04-23 20:47  一毛_  阅读(189)  评论(0编辑  收藏  举报

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

题目大意:

  给定一个有向图,n个点,m条边( 1<=n<=100, m<=n^2 ),点有三类: np个 power station,nc个consumer,其余的是普通的点,其中np个power station可以产生power供给网络传递,nc个consumer消耗能量,每个power station有一个最大的供应值value,每个consumer有一个最大的消耗值value,问最终可以消耗能量的最大值;

分析:

  我的构图方式: 虚拟一个源点S(S=0),其余输入的点都+1,虚拟一个汇点T(T=n+1),S向所有的power station引一条边,边权(容量)为相应的power station的value值,所有的consumer向T引一天边,边权(容量)为相应consumer的value值;

  之后用Edmond_karp模版求最大流即可;

注意:

  我开始想用%*来处理一些多余的空格,回车的输入,后来失败了,后来读入m个串,np个串,nc个串来解决问题(下面的代码就是这样),然后又看了大众的代码,发现都是这样输入的:

scanf(" (%d,%d)%d", ...); // 即括号前面加了空格;

scanf(" (%d)%d", ...);

代码:

poj1459
  1 /*1459    Accepted    212K    375MS    C++    2908B    2012-04-23 19:59:30*/
  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 110
 18 #define inf 2100000000
 19 int n, np, nc, m, S, T;
 20 int mark[maxn]; // 0: station;  1: consumer; 2: anthter;
 21 // all station should be linked to the sourse; and all consumer should be linked to the sink;
 22 int g[maxn][maxn];
 23 void Read(){
 24     int i,j,u,v,w;
 25     char ch[100];
 26     for(i=0;i<=n+1;++i)
 27         for(j=0;j<=n+1;++j)
 28             g[i][j]= 0;
 29 
 30     for(i=1;i<=m;++i){
 31         //scanf( "%*[ ]%*['\n'](%d,%d)%d", &u, &v, &w );
 32         //scanf( "%*[ ](%d,%d)%d", &u, &v, &w );
 33         scanf("%s", ch);
 34         u= 0;
 35         for(j=1;ch[j]!=',';++j)
 36             u= u*10 + ch[j]-'0';
 37         v= 0;
 38         for(++j;ch[j]!=')';++j)
 39             v= v*10 + ch[j]-'0';
 40         w= 0;
 41         for(++j;ch[j];++j)
 42             w= w*10 + ch[j]-'0';
 43         ++u, ++v;
 44         g[u][v]= w;
 45     }
 46 
 47 
 48     for(i=1;i<=np;++i){
 49         //scanf("%*[ ](%d)%d", &u, &w);
 50         //scanf("%*[ ]%*['\n'](%d)%d", &u, &w);
 51         scanf("%s", ch);
 52         u= 0;
 53         for(j=1;ch[j]!=')';++j)
 54             u= u*10 + ch[j]-'0';
 55         w= 0;
 56         for(++j;ch[j];++j)
 57             w= w*10 + ch[j]-'0';
 58         ++u;
 59         g[0][u]= w;
 60     }
 61     for(i=1;i<=nc;++i){
 62         //scanf("%*[ ](%d)%d", &u, &w);
 63         //scanf("%*[ ]%*['\n'](%d)%d", &u, &w);
 64         scanf("%s", ch);
 65         u= 0;
 66         for(j=1;ch[j]!=')';++j)
 67             u= u*10 + ch[j]-'0';
 68         w= 0;
 69         for(++j;ch[j];++j)
 70             w= w*10 + ch[j]-'0';
 71         ++u;
 72         g[u][T]= w;
 73     }
 74 }
 75 
 76 int pre[maxn];
 77 int que[maxn];
 78 bool vis[maxn];
 79 bool bfs(){
 80     MM( vis, 0 );
 81     int head= 0, tail= 0;
 82     que[tail++]= S;
 83     vis[S]= 1;
 84     while(head<tail){
 85         int u= que[head++];
 86         for(int i=1;i<=T;++i){
 87             if( g[u][i] && !vis[i] ){
 88                 vis[i]= 1;
 89                 pre[i]= u;
 90                 if(i==T) return 1;
 91                 que[tail++]= i;
 92             }
 93         }
 94     }
 95     return 0;
 96 }
 97 int Edmond_karp(){
 98     int i,ans= 0;
 99     while( bfs() ){
100         int t= inf;
101         for(i= T; i!= S; i= pre[i])
102             up_min( t, g[pre[i]][i] );
103         ans+= t;
104         for(i=T; i!=S; i= pre[i]){
105             g[pre[i]][i]-= t;
106             g[i][pre[i]]+= t;
107         }
108     }
109     return ans;
110 }
111 
112 int main()
113 {
114     while( scanf("%d%d%d%d", &n, &np, &nc, &m) != EOF ){
115         S= 0, T= n+1;
116         Read();
117         printf("%d\n", Edmond_karp() );
118     }
119 }