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

POJ 1459 Power Network(网络最大流,dinic算法模板题)

2013-10-24 22:16 429 查看
题意:给出n,np,nc,m,n为节点数,np为发电站数,nc为用电厂数,m为边的个数。
接下来给出m个数据(u,v)z,表示w(u,v)允许传输的最大电力为z;np个数据(u)z,表示发电站的序号,以及最大的发电量;
nc个数据(u)z,表示用电厂的序号,以及最大的用电量。
最后让你求可以供整个网络使用的最大电力。
思路:纯模板题。
这里主要是设一个源点s和一个汇点t,s与所有发电厂相连,边的最大容量为对应发电厂的最大发电量;
t与所有用电厂相连,边的最大容量为对应用电厂的最大用电量。
因为节点编号0~n-1,所以这里s设为n,t设为n+1。
接着求最大流即可。

#include <iostream>
#include <stdio.h>
#include <algorithm>
#include <string.h>
#include <queue>

using namespace std;
const int INF=0x3f3f3f3f;
const int maxn=110;
int pri[maxn]; //用来记录增广路
int n,np,nc,m; //n为节点数,np为发电站数,nc为用电厂数,m为边的个数。
int s,t,sum;  //源点,汇点,最大流
struct Edge{
int c,f; //c为容量,f为流
}edge[maxn][maxn];
bool BFS() {
queue<int> q;
memset(pri,0,sizeof(pri));
pri[s]=1;
q.push(s);
while(!q.empty()) {
int temp=q.front();
q.pop();
for(int i=0; i<=n+1; i++) {
if(!pri[i] && edge[temp][i].c-edge[temp][i].f){
pri[i]=pri[temp]+1;
if(i==t)
return true;    //即如果可以流到汇点,直接return true
q.push(i);
}
}
}
return false;
}

//p表示当前节点,flow表示该节点通过的流量
int dinic(int p,int flow){
if(p==t){
return flow;
}
int f=flow;
for(int i=0;i<=n+1;i++){
if(pri[i]==pri[p]+1 && edge[p][i].c-edge[p][i].f){
int a=edge[p][i].c-edge[p][i].f;  //a为该边可以增加的流量
int ff=dinic(i,min(a,flow));  //ff为路径中所有a的最小值,即为该条路中可以增加的流量
edge[p][i].f+=ff;       //正向边
edge[i][p].f-=ff;       //逆向边,逆向边的c为0,f为负值,这样c-f即为正向边的目前流量,即可以“退流”的量
flow-=ff;
}
}
return f-flow;
}
int main()
{
int u,v,z;
while(scanf("%d%d%d%d",&n,&np,&nc,&m)!=EOF){
sum=0;
s=n;t=n+1;
for(int i=0;i<maxn;i++){
for(int j=0;j<maxn;j++)
edge[i][j].c=edge[i][j].f=0;
}
for(int i=1;i<=m;i++){
while(getchar()!='('); //要加上这句。
scanf("%d,%d)%d",&u,&v,&z);
//printf("%d %d %d\n",u,v,z);
edge[u][v].c=z;
}
for(int i=0;i<np;i++){
while(getchar()!='(');
scanf("%d)%d",&u,&z);
//printf("%d %d\n",u,z);
edge[s][u].c=z;
}
for(int i=0;i<nc;i++){
while(getchar()!='(');
scanf("%d)%d",&u,&z);
//printf("%d %d\n",u,z);
edge[u][t].c=z;
}
//如能找到增广路,则sum加上增加的流量
while(BFS()){
sum+=dinic(s,INF);
}
printf("%d\n",sum);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: