• 【[ZJOI2010]网络扩容】


    题目

    第一问直接板子敲上去

    第二问并不明白直接在残量网络上加边的神仙做法

    非常显然我们需要让流量加(k),那么我们就使得网络里的总流量为(maxf+k)(maxf)是第一问求出来的最大流

    所以搞一个超级源点,向(1)连一条流量是(maxf+k)费用是(0)的边,之后在原来的图的基础上再给每条边加一条流量为(inf),费用为相应费用的边

    这样让它自己在里面流就必然会流出来(maxf+k)的流量

    求出最小费用就好了

    代码

    #include<algorithm>
    #include<iostream>
    #include<cstring>
    #include<cstdio>
    #include<queue>
    #define maxn 1005
    #define re register
    #define LL long long
    #define inf 999999999
    #define max(a,b) ((a)>(b)?(a):(b))
    #define min(a,b) ((a)<(b)?(a):(b))
    inline int read()
    {
        char c=getchar();int x=0;while(c<'0'||c>'9') c=getchar();
        while(c>='0'&&c<='9') x=(x<<3)+(x<<1)+c-48,c=getchar();
        return x;
    }
    struct E{int v,nxt,w,f;} e[20005];
    int d[maxn],vis[maxn],head[maxn];
    int n,m,num=1,K,S,T;
    int a[5005],b[5005],c[5005],t[5005];
    inline void add(int x,int y,int ca,int z){e[++num].v=y;e[num].nxt=head[x];e[num].f=ca,e[num].w=z;head[x]=num;}
    inline void C(int x,int y,int ca,int z){add(x,y,ca,z),add(y,x,0,-1*z);}
    inline int SPFA()
    {
        std::queue<int> q;
        for(re int i=S;i<=T;i++) d[i]=inf,vis[i]=0;
        d[T]=0,vis[T]=1,q.push(T);
        while(!q.empty())
        {
            int k=q.front();q.pop();vis[k]=0;
            for(re int i=head[k];i;i=e[i].nxt)
            if(e[i^1].f&&d[e[i].v]>d[k]+e[i^1].w)
            {
                d[e[i].v]=d[k]+e[i^1].w;
                if(!vis[e[i].v]) vis[e[i].v]=1,q.push(e[i].v);
            }
        }
        return d[S]<inf;
    }
    int dfs(int x,int now)
    {
        if(x==n||!now) return now;
        int flow=0,ff;vis[x]=1;
        for(re int i=head[x];i;i=e[i].nxt)
        if(e[i].f&&!vis[e[i].v]&&d[e[i].v]==d[x]+e[i^1].w)
        {
            ff=dfs(e[i].v,min(e[i].f,now));
            if(ff<=0) continue;
            now-=ff,flow+=ff;
            e[i].f-=ff,e[i^1].f+=ff;
            if(!now) break;
        }
        return flow;
    }
    int main()
    {
        n=read(),m=read(),K=read();S=1,T=n;
        int x,y,ca,z,ans=0,tot=0,Mf=0;
        for(re int i=1;i<=m;i++) 
            x=read(),y=read(),ca=read(),z=read(),C(x,y,ca,0),a[i]=x,b[i]=y,c[i]=ca,t[i]=z;
        while(SPFA())
        {
            vis[T]=1;
            while(vis[T]) 
            {
                for(re int i=S;i<=T;i++) vis[i]=0;
                int F=dfs(S,inf);
                ans+=F;
            }
        }
        printf("%d ",ans);
        num=1,memset(head,0,sizeof(head)),memset(e,0,sizeof(e));
        for(re int i=1;i<=m;i++) C(a[i],b[i],inf,t[i]),C(a[i],b[i],c[i],0);
        S=0,C(S,1,ans+K,0);ans=0;
        while(SPFA())
        {
            vis[T]=1;
            while(vis[T]) 
            {
                for(re int i=S;i<=T;i++) vis[i]=0;
                int F=dfs(S,inf);
                ans+=F*d[S];
            }
        }
        printf("%d
    ",ans);
        return 0;
    }
    
  • 相关阅读:
    justep w模型检查正常,编译出错
    php get post 发送与接收
    编译原理正则文本与有限状态机
    编译原理前端技术
    lucene早期版本基本概念
    golang panic和defer
    2021年1月阅读文章
    elasticsearch 中的fielddata 和 doc_values
    golang中的树
    elasticsearch中的wildcard
  • 原文地址:https://www.cnblogs.com/asuldb/p/10281691.html
Copyright © 2020-2023  润新知