poj1459(多源点网络流)

题意:有n个点,np个供电点,nc个消费点,m条线路,接来题目先给出的是m条带权路径,然后是np个供电点和权值,接着就是nc个消费点和权值。 
题目要我们求出给定的图最大能消费的总电量(就是求最大流)

思路:建一个超级源点,一个超级汇点。超级源点连接所以供电站,所以消费点连接超级汇点。跑一遍网络流即可。

代码:

#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<queue>
#define inf 0x3f3f3f3f
using namespace std;
typedef long long ll;

struct node{
    int c,f;
}mp[310][310];
int sx,ex,n,m,np,nc;
int pre[310];


bool bfs()
{
    memset(pre,0,sizeof(pre));
    pre[sx]=1;
    queue<int> q;
    q.push(sx);
    while(!q.empty())
    {
        int p=q.front();
        q.pop();
        for(int i=0;i<=n+1;i++)
        {
            if(!pre[i]&&mp[p][i].c-mp[p][i].f)
            {
                pre[i]=pre[p]+1;
                q.push(i);
            }
        }
    }
    return pre[ex]!=0;
}

int dinic(int pos,int flow)
{
    int f=flow;
    if(pos==ex)
           return flow;
    for(int i=0;i<=n+1;i++)
    {
        if(mp[pos][i].c-mp[pos][i].f&&pre[pos]+1==pre[i])
        {
            int a=mp[pos][i].c-mp[pos][i].f;
            int t=dinic(i,min(a,flow));
            mp[pos][i].f+=t;
            mp[i][pos].f-=t;
            flow-=t;
        }
    }
    return f-flow;
}

int solve()
{
    int sum=0;
    while(bfs())
    {
        sum+=dinic(sx,inf);
    }
    return sum;
}

int main()
{
    while(cin>>n>>np>>nc>>m)
    {
        int st,ed,v;
        char f;
        sx=n;ex=n+1;
        memset(mp,0,sizeof(mp));
        for(int i=1;i<=m;i++)
        {
            cin>>f>>st>>f>>ed>>f>>v;
            if(st==ed)
                continue;
            mp[st][ed].c+=v;    
        }
        for(int i=1;i<=np;i++)
        {
            cin>>f>>st>>f>>v;
            mp[sx][st].c+=v;
        }
        for(int i=1;i<=nc;i++)
        {
            cin>>f>>ed>>f>>v;
            mp[ed][ex].c+=v;
        }
        cout<<solve()<<endl;
    }    
    return 0;
}

 

posted @ 2019-07-05 13:23  怀揣少年梦.#  阅读(297)  评论(0编辑  收藏  举报