POJ 1459 Power Network

Power Network

题意:n个点(0~n-1),m条边,np个源点,nc个汇点,有各自的流量限制,问同一时刻所有源点到汇点的最大流


思路:最大流,建图,EK


解题方法:新增起始点n,与所有源点相连通;新增终点n+1,与所有汇点相连通,此时就变成求结点n到结点n+1的最大流


注意:这里用的是理解矩阵存的边,刚开始用了vector的邻接表发现超时了


代码如下:

#include<iostream>
#include<cstdio>
#include<queue>
#include<cstring>
#define N 110
#define INF 0x3f3f3f3f
typedef long long LL;
using namespace std;
int cap[N][N],flow[N][N],low[N],pre[N];
queue<int>Q;
void init(){
    memset(cap,0,sizeof(cap));
    memset(flow,0,sizeof(flow));
    while(!Q.empty()) Q.pop();
}
void add(int from,int to,int c){
    cap[from][to]+=c;
}
int EK(int s,int t){
    int max_flow = 0;
    while(1){
        Q.push(s);
        memset(low,0,sizeof(low));
        low[s]=INF;
        while(!Q.empty()){
            int u = Q.front();
            Q.pop();
            for(int v=0;v<=t;v++){
                if(!low[v]&&cap[u][v]>flow[u][v]){
                    Q.push(v);
                    low[v]=min(low[u],cap[u][v]-flow[u][v]);
                    pre[v]=u;

                }
            }
        }
        if(low[t]==0) break;
        for(int u=t;u!=s;u=pre[u]){
            flow[pre[u]][u]+=low[t];
            flow[u][pre[u]]-=low[t];
        }
        max_flow+=low[t];
    }
    return max_flow;
}
int main(){
    int n,np,nc,m,a,b,c;
    while(scanf("%d%d%d%d",&n,&np,&nc,&m)!=EOF){
        init();
        while(m--){
            scanf(" (%d,%d)%d",&a,&b,&c);
            add(a,b,c);
        }
        while(np--){
            scanf(" (%d)%d",&a,&c);
            b=a,a=n;
            add(a,b,c);
        }
        while(nc--){
            scanf(" (%d)%d",&a,&c);
            b=n+1;
            add(a,b,c);
        }
        printf("%d\n",EK(n,n+1));
    }
    return 0;
}



猜你喜欢

转载自blog.csdn.net/const_qiu/article/details/47091443