POJ 1459 Power Network

题意:有n个据点,np个发电机。nc个用户,m条电线。给出发电机。用户。电线的电流限制,求最大网络电流。

这是带节点的网络流。事实上和原来没什么差别,仅仅要在前后都添加一个据点,在这里我加了0和n+1两个节点,而发电机节点的电流限制能够

转化为0->节点的电流限制,用户节点电流的限制能够转化为节点->n+1的电流限制,之后套用最大网络流模板就可以。这里我写了,Edmonds_karp算法。

稍后传上Dinic算法。。。

。。。。。。。。。。。。。

。。



AC代码例如以下:


Edmonds_karp算法


#include <iostream>
#include <cstdio>
#include <queue>
#include <cstring>
#define min(a,b) (a<b?a:b)
#define inf 100000000
using namespace std;

int n,np,nc,m;
int map[105][105],jd[105],p[105],f[105];


int Edmonds_karp(int s,int e)
{
    int i,j;
    queue <int > q;
    int a,b;
    for(i=0;i<=n+1;i++)
        p[i]=-1;
    f[0]=inf;
    q.push(s);
    while(!q.empty())
    {
        b=q.front ();
        q.pop();
        if(b==e)
            break;
        for(i=0;i<=n+1;i++)
        {
            if(p[i]==-1&&map[b][i]>0)
            {
                f[i]=min(map[b][i],f[b]);
                p[i]=b;
                q.push(i);
            }
        }
    }
    if(p[e]==-1)
        return -1;
    else return f[e];
}

int maxflow(int s,int e)
{
    int i,j;
    int a,ans=0;
    a=Edmonds_karp(s,e);
    while(a!=-1)
    {
        int k=e,min=inf;
        while(k!=s)
        {
            map[p[k]][k]-=a;
            map[k][p[k]]+=a;
            k=p[k];
        }
        ans+=a;
        a=Edmonds_karp(s,e);
    }
    return ans;
}


int main()
{
    int i,j;
    int a,b,c,d,f;
    char z,x,y;
    while(cin>>n>>np>>nc>>m)
    {
        memset(map,0,sizeof map);
        for(i=1;i<=m;i++)
        {
            cin>>z>>a>>x>>b>>y>>c;
            map[a+1][b+1]+=c;
        }
        for(i=1;i<=np;i++)
        {
            cin>>z>>d>>x>>f;
            map[0][d+1]+=f;
        }
        for(i=1;i<=nc;i++)
        {
            cin>>z>>d>>x>>f;
            map[d+1][n+1]+=f;
        }
        cout<<maxflow(0,n+1)<<endl;

    }

    return 0;
}

Dinic算法

#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
#define inf 100000000
#define min(a,b) (a<b?a:b)
using namespace std;

int n,np,nc,m;
int map[105][105],cs[105];

int bfs()
{
    int i,j;
    queue <int > q;
    int a,b;
    memset(cs,-1,sizeof cs);
    cs[0]=0;
    q.push(0);
    while(!q.empty())
    {
        b=q.front ();
        q.pop();

        for(i=0;i<=n+1;i++)
        {
            if(cs[i]==-1&&map[b][i]>0)
            {
                cs[i]=cs[b]+1;
                q.push(i);
            }
        }
    }
    if(cs[n+1]==-1)
        return 0;
    else return 1;

}

int dfs(int s,int mf)
{
    int i,j;
    int a,b;
    if(s==n+1)
        return mf;
    for(i=0;i<=n+1;i++)
    {
        if(cs[i]==cs[s]+1&&map[s][i]>0&&(a=dfs(i,min(mf,map[s][i]))))
        {
            map[s][i]-=a;
            map[i][s]+=a;
            return a;
        }
    }
    return 0;
}

int main()
{
    int i,j;
    int a,b,c,d,f;
    while(cin>>n>>np>>nc>>m)
    {
        memset(map,0,sizeof map);
        for(i=1;i<=m;i++)
        {
            scanf(" (%d,%d)%d",&a,&b,&c);
            map[a+1][b+1]+=c;
        }
        for(i=1;i<=np;i++)
        {
            scanf(" (%d)%d",&d,&f);
            map[0][d+1]+=f;
        }
        for(i=1;i<=nc;i++)
        {
            scanf(" (%d)%d",&d,&f);
            map[d+1][n+1]+=f;
        }
        int ans=0,sum;
        while(bfs())
        {
            while(sum=dfs(0,inf))
                ans+=sum;
        }
        cout<<ans<<endl;
    }
    return 0;
}

posted @ 2017-08-10 17:18  wzjhoutai  阅读(108)  评论(0编辑  收藏  举报