题目链接: 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 }