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

题意:给出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
",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
",u,z);
            edge[s][u].c=z;
        }
        for(int i=0;i<nc;i++){
            while(getchar()!='(');
            scanf("%d)%d",&u,&z);
//printf("%d %d
",u,z);
            edge[u][t].c=z;
        }
        //如能找到增广路,则sum加上增加的流量
        while(BFS()){
            sum+=dinic(s,INF);
        }
        printf("%d
",sum);
    }
    return 0;
}
原文地址:https://www.cnblogs.com/chenxiwenruo/p/3386913.html