您的位置:首页 > 其它

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

2012-04-23 20:47 260 查看
题目链接: 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

/*1459    Accepted    212K    375MS    C++    2908B    2012-04-23 19:59:30*/
#include <cstdio>
#include <cstring>
#include <cmath>
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;

#define mpair make_pair
#define pii pair<int,int>
#define MM(a,b) memset(a,b,sizeof(a));
typedef long long lld;
typedef unsigned long long u64;
template<class T> bool up_max(T& a,const T& b){return b>a? a=b,1 : 0;}
template<class T> bool up_min(T& a,const T& b){return b<a? a=b,1 : 0;}
#define maxn 110
#define inf 2100000000
int n, np, nc, m, S, T;
int mark[maxn]; // 0: station;  1: consumer; 2: anthter;
// all station should be linked to the sourse; and all consumer should be linked to the sink;
int g[maxn][maxn];
void Read(){
int i,j,u,v,w;
char ch[100];
for(i=0;i<=n+1;++i)
for(j=0;j<=n+1;++j)
g[i][j]= 0;

for(i=1;i<=m;++i){
//scanf( "%*[ ]%*['\n'](%d,%d)%d", &u, &v, &w );
//scanf( "%*[ ](%d,%d)%d", &u, &v, &w );
scanf("%s", ch);
u= 0;
for(j=1;ch[j]!=',';++j)
u= u*10 + ch[j]-'0';
v= 0;
for(++j;ch[j]!=')';++j)
v= v*10 + ch[j]-'0';
w= 0;
for(++j;ch[j];++j)
w= w*10 + ch[j]-'0';
++u, ++v;
g[u][v]= w;
}

for(i=1;i<=np;++i){
//scanf("%*[ ](%d)%d", &u, &w);
//scanf("%*[ ]%*['\n'](%d)%d", &u, &w);
scanf("%s", ch);
u= 0;
for(j=1;ch[j]!=')';++j)
u= u*10 + ch[j]-'0';
w= 0;
for(++j;ch[j];++j)
w= w*10 + ch[j]-'0';
++u;
g[0][u]= w;
}
for(i=1;i<=nc;++i){
//scanf("%*[ ](%d)%d", &u, &w);
//scanf("%*[ ]%*['\n'](%d)%d", &u, &w);
scanf("%s", ch);
u= 0;
for(j=1;ch[j]!=')';++j)
u= u*10 + ch[j]-'0';
w= 0;
for(++j;ch[j];++j)
w= w*10 + ch[j]-'0';
++u;
g[u][T]= w;
}
}

int pre[maxn];
int que[maxn];
bool vis[maxn];
bool bfs(){
MM( vis, 0 );
int head= 0, tail= 0;
que[tail++]= S;
vis[S]= 1;
while(head<tail){
int u= que[head++];
for(int i=1;i<=T;++i){
if( g[u][i] && !vis[i] ){
vis[i]= 1;
pre[i]= u;
if(i==T) return 1;
que[tail++]= i;
}
}
}
return 0;
}
int Edmond_karp(){
int i,ans= 0;
while( bfs() ){
int t= inf;
for(i= T; i!= S; i= pre[i])
up_min( t, g[pre[i]][i] );
ans+= t;
for(i=T; i!=S; i= pre[i]){
g[pre[i]][i]-= t;
g[i][pre[i]]+= t;
}
}
return ans;
}

int main()
{
while( scanf("%d%d%d%d", &n, &np, &nc, &m) != EOF ){
S= 0, T= n+1;
Read();
printf("%d\n", Edmond_karp() );
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: