F - Power Network dinic

n个点,np个供电站,nc个消费站,剩下的(n-np-nc)个都是中转站,m条线路

问你最大可接受供电是多少,Dinic直接上

只有供电站可以和源点连边,只有消费站可以跟汇点连边

#include<stdio.h>
#include<string.h>
#include<iostream>
#include<queue>
#include<algorithm>
#define inf 0x3f3f3f3f
using namespace std;
int n,np,nc,m,cnt,st,T;
struct node
{
    int v,cap,to;
}s[50000];
int head[3000],dis[3000];
void add(int u,int v,int cap)
{
    s[cnt].v=v;
    s[cnt].cap=cap;
    s[cnt].to=head[u];
    head[u]=cnt++;
    s[cnt].v=u;
    s[cnt].cap=0;
    s[cnt].to=head[v];
    head[v]=cnt++;
}
queue<int>q;
bool bfs()
{
    memset(dis,0,sizeof(dis));
    while(!q.empty())
        q.pop();
    dis[0]=1;
    q.push(0);
    while(!q.empty())
    {
        int u=q.front();
        q.pop();
        for(int e=head[u];~e;e=s[e].to)
        {
            int v=s[e].v,cap=s[e].cap;
            if(dis[v]==0&&cap>0)
            {
                dis[v]=dis[u]+1;
                q.push(v);
            }
        }
    }
    return dis[T]!=0;
}
int dfs(int u,int flow)
{  int mm;
    if(u==T)
        return flow;
    for(int e=head[u];~e;e=s[e].to)
    {
        int v=s[e].v,cap=s[e].cap;
        if(dis[v]==dis[u]+1&&cap>0&&(mm=dfs(v,min(cap,flow))))
        {
            s[e].cap-=mm;
            s[e^1].cap+=mm;
            return mm;
        }
    }
    dis[u]=-1;//注意这里
    return 0;
}
int dinic()
{
    int ans=0,tf;
    while(bfs())
    {//printf("*\n");
        while(tf=dfs(0,inf))
        {
            ans+=tf;
        }
    }
    return ans;
}
int main()
{
    while(~scanf("%d%d%d%d",&n,&np,&nc,&m))
    {   int a,b,c;T=n+1;cnt=0;
        char ch;
        memset(head,-1,sizeof(head));
        int u,v,z;
        for(int i=0;i<m;i++)
        {
            ch=getchar();
            while(ch!='(')
                    ch=getchar();
           scanf("%d,%d)%d",&u,&v,&z);
           add(u+1,v+1,z);
        }
        for(int i=0;i<np;i++)
        {
             ch=getchar();
            while(ch!='(')
                    ch=getchar();
           scanf("%d)%d",&u,&z);
           add(0,u+1,z);
        }
        for(int i=0;i<nc;i++)
        {
             ch=getchar();
            while(ch!='(')
                    ch=getchar();
            scanf("%d)%d",&u,&z);
            add(u+1,n+1,z);
        }
         st=0;
        printf("%d\n",dinic());
    }
}

猜你喜欢

转载自blog.csdn.net/Kuguotao/article/details/83548176