【网络流】【最大流】【EK::EK(BFS)】POJ1459 Power Network

【题意】n个节点,其中np个发电厂,nc个用户,其他是过路点。有m条边,从a到b最大运输w单位的电。发电厂有最大出电量,用户有最大入电量。问用户最终能得到多少电。

【思路】超级源点指向所有的发电站,容量是发电站的发电量,所有的用户指向超级汇点,容量是用电量,其他边按题意建。

【重点】【EK算法】建图之后就是跑FF...结果T了...果然DFS是要比BFS慢的...用EK过。

              【路径的存储】DFS是递归的,它的path可以一个个点存储,但是BFS事先不知道能否到达终点,所以path[a]要存a的前面的节点。

【代码】

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
const int M=2505;
const int inf=99999999;

int mp[M][M];
int n,m,np,nc;
int start,end;
int pathf[M];
int temp,ans;
std::queue<int>q;


void bfs(int x)
{
    while(!q.empty())
        q.pop();
    pathf[x]=0;
    q.push(x);
    while(!q.empty())
    {

        int t=q.front();
        if(t==end)
            return;
        for(int i=0; i<=end; i++)//
        {
            if(mp[t][i]>0&&pathf[i]==-1)
            {
                pathf[i]=t;//现在path不是一个个存了,path[a]里存的是a的前一个节点。
                q.push(i);
            }
        }
        q.pop();
    }
    return;
}

int main()
{
    while(~scanf("%d%d%d%d",&n,&np,&nc,&m))
    {
        ans=0;
        memset(mp,0,sizeof(mp));
        start=0,end=n+1;
        while(m--)
        {
            int f,t,w;
            while(getchar()!='(');
            scanf("%d,%d)%d",&f,&t,&w);
            f++;
            t++;
            mp[f][t]=w;
        }
        for(int i=0; i<np; i++)
        {
            int t,w;
            while(getchar()!='(');
            scanf("%d)%d",&t,&w);
            t++;
            mp[start][t]=w;
        }
        for(int i=0; i<nc; i++)
        {
            int t,w;
            while(getchar()!='(');
            scanf("%d)%d",&t,&w);
            t++;
            mp[t][end]=w;
        }

        while(1)
        {
//            for(int i=0; i<=n+1; i++)
//            {
//                for(int j=0; j<=n+1; j++)
//                {
//                    printf("%d ",mp[i][j]);
//                }
//                printf("\n");
//            }
//            puts("");
            temp=inf;
            memset(pathf,-1,sizeof(pathf));

            bfs(start);

            int now=end;
            if(pathf[end]==-1)
                break;
            while(now!=start)
            {
                int pre=pathf[now];//
                temp=std::min(temp,mp[pre][now]);
                now=pre;
            }
            now=end;
            while(now!=start)
            {
                int pre=pathf[now];
                mp[pre][now]-=temp;
                mp[now][pre]+=temp;
                now=pre;
            }
            ans+=temp;
        }
        printf("%d\n",ans);
    }

}

猜你喜欢

转载自blog.csdn.net/qq_32259423/article/details/81356692