zoukankan      html  css  js  c++  java
  • 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;
    }
  • 相关阅读:
    字幕文件srt处理之pysrt
    python 多进程代码问题以及用 pyinstaller 打包成exe 问题解决
    ffmpeg的安装以及使用
    人声识别之webrtcvad
    python3安装dlib库和face_recognition库
    python实现 请按任意键继续。。。
    python 模块tkinter之filedalog
    古诗文网验证码识别
    xpath案例-全国城市名爬取
    xpath案例-4K图片爬取
  • 原文地址:https://www.cnblogs.com/chenxiwenruo/p/3386913.html
Copyright © 2011-2022 走看看