Uva(10330)

这题的题意是给出n的点,每个点有容量限制,然后给出每条边的运输的容量,问你从XX城市运送电量到YY城市最大的电量是多少。。

最大流的模板题,直接用EK算法。。XX城市设定0,YY城市为n+1。还有一点要注意的是在求最小的残量的是还要看每个顶点容量。。

#include<stdio.h>
#include<string.h>
#include<iostream>
#include<queue>
#include<algorithm>
using namespace std;
const int inf=99999999;
const int N=110;
int f[N],a[N],cap[N][N],flow[N][N],p[N];
using namespace std;
int n;
int F;
int s,t;
void EK_()
{
    queue<int>q;
    memset(flow,0,sizeof(flow));
    for(;;)
    {
        memset(a,0,sizeof(a));
        q.push(s);
        a[s]=inf; 
        while(!q.empty())
        {
            int u=q.front();
            q.pop();
            for(int v=0;v<=n+1;v++)
            { 
            if(!a[v]&&cap[u][v]>flow[u][v]&&flow[u][v]<f[u]&&flow[u][v]<f[v])//看当前流量是否小于顶点的容量
            {
            p[v]=u;
            q.push(v);
            a[v]=min(a[u],cap[u][v]-flow[u][v]);
            a[v]=min(a[v],f[u]-flow[u][v]);
            a[v]=min(a[v],f[v]-flow[u][v]);//在边之间的容量和顶点之间的容量求一个最小值作为最小的残量
            }
        } 
        }    
        if(a[t]==0)
        break;
        for(int u=t;u!=s;u=p[u])
        {
            flow[p[u]][u]+=a[t];
            flow[u][p[u]]-=a[t];
        }
        F+=a[t];
    }
}
int main()
{
    while(scanf("%d",&n)!=EOF)
    {
        s=0,t=n+1;
        F=0;
        for(int i=1;i<=n;i++)
        {
            scanf("%d",&f[i]);
        }
        int m;
        scanf("%d",&m);
        int aa,b,c;
        memset(cap,0,sizeof(cap));
        while(m--)
        {
            scanf("%d %d %d",&aa,&b,&c);
            cap[aa][b]=c;
        }
        int B,D;
        scanf("%d %d",&B,&D);
        int x;
        for(int i=0;i<B;i++)
        {
            scanf("%d",&x);
            cap[0][x]=inf;
        }
        for(int i=0;i<D;i++)
        {
            scanf("%d",&x);
            cap[x][n+1]=inf;
        }
        f[0]=f[n+1]=inf;
        EK_();
        printf("%d\n",F);
    }
    return 0;
}

 

posted @ 2015-12-31 08:43  __NaCl  阅读(105)  评论(0编辑  收藏  举报