您的位置:首页 > 理论基础 > 计算机网络

POJ 1459 Power Network (最大流, 网络流, EdmondsKarp算法求解最大流)

2017-03-22 16:33 597 查看
题意:  给定np个发电站, nc个消费者, m条从u流到v的边, 其权值为边的最大容量, 求解, 消费者总的最大可用电量

求解:  增加两个点:源点以及汇点,  源点指向所有的发电站(即给发电站提供电量, 但是每个发电站最大接收量已被限制), 所有的消费者指向汇点(即消费者所能用的电量全部汇聚到该汇点上,每个消费者能用的电量有最大限制), 构建网络流模型, 用EdmondsKarp算法求解

code:

/*
s(u)  u被提供的能量数
p(u)  0<=p(u)<=Pmax(u) u产生的能量数
c(u)  u消耗的能量数  (0<=c(u)<=minn(s(u), Cmax(u)))
d(u)  u向外传递的能量数 = s(u)+p(u)-c(u)
每个发电站         c(u) = 0;
每个消费者(用电者)  p(u)=0;
每个调度员   c(u)=0 && p(u)=0;
u到v至多一条电力通路
l(u, v) u传送到v的总能量数
Con = EuC(u), 消耗总和
求Con最大值
*/
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<queue>
using namespace std;
const int maxn = 205;
const int inf = 0x3f3f3f3f3f;
int n, np, nc, m, s, e;//s->源点,  e->汇点
//n:nodes
//np: power stations 发电站数
//nc: consumers  消费者数
//m: 电力通路数
int edge[maxn][maxn];// u-v之间电力通路传送最大值
int flow[maxn], vis[maxn];
int pre[maxn];
//找出所有增广路, 每找出一条就在各个边上去掉汇点上所获得的能量
int bfs(){
int i, v;
queue<int>que;
memset(flow, -1, sizeof(flow));
memset(vis, 0, sizeof(vis));
while(!que.empty()) que.pop();
que.push(s);
vis[s] = 1;
flow[s] = inf;
pre[s] = s;
while(!que.empty()){
v = que.front();
que.pop();
for(i=s; i<=e; i++){
if(vis[i]&&edge[v][i]){
vis[i] = 1;
flow[i] = min(flow[v], edge[v][i]);
que.push(i);
pre[i] = v;
}
}
}
if(flow[e]!=-1){
return flow[e];
} else {
return 0;
}
}
int EdmondsKarp(){
int i, MIN;
int maxflow = 0;
while(MIN=bfs()){
for(i=e; i!=s; i=pre[i]){
edge[pre[i]][i] -= MIN;//正向边
edge[i][pre[i]] += MIN;//反向边
}
maxflow += MIN;
}
return maxflow;
}
int main()
{
int i, j, k;
char c;
while(~scanf("%d %d %d %d%*c", &n, &np, &nc, &m)){
s=0, e=n+1;
memset(edge, 0, sizeof(edge));
int x, y, z;
for(i=1; i<=m; i++){
while((c=getchar())!='(');
scanf("%d,%d)%d", &x, &y, &z);
if(x==y) continue;
edge[x+1][y+1]+=z;
}
for(i=1; i<=np; i++){
while((c=getchar())!='(');
scanf("%d)%d", &x, &z);
edge[s][x+1] = z;//源点与每个发电站建立联系
}
for(i=1; i<=nc; i++){
while((c=getchar())!='(');
scanf("%d)%d", &x, &z);
edge[x+1][e] = z;//汇点与每个消费者建立联系
}
printf("%d\n", EdmondsKarp());
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: