• [ZJOI2010] 网络扩容


    题意:

    给定一张有向图,每条边都有一个容量c和一个扩容费用w。这里扩容费用是指将容量扩大1所需的费用。

    求: 在不扩容的情况下,1到n的最大流;将1到n的最大流增加k所需的最小扩容费用。

    $nleq 1000,mleq 5000$。

    题解:

    先跑一边最大流,然后对每条边$(u,v,c,0)$再建一条$(u,v,inf,w)$的边。

    源点限流为k,在残量网络上再跑一遍最小费用最大流即可。

    复杂度$O(能过)$。

    代码:

    #include<bits/stdc++.h>
    #define maxn 1005
    #define maxm 100005
    #define inf 0x7fffffff
    #define ll long long
    #define rint register int
    #define debug(x) cerr<<#x<<": "<<x<<endl
    #define fgx cerr<<"--------------"<<endl
    #define dgx cerr<<"=============="<<endl
    
    using namespace std;
    int n,m,k,hd[maxn],to[maxm],fl[maxm],nxt[maxm],cnt;
    int dis[maxn],inq[maxn],cst[maxm],vis[maxn],cost;
    struct edge{int u,v,c,w;}E[maxm];
    
    inline int read(){
        int x=0,f=1; char c=getchar();
        for(;!isdigit(c);c=getchar()) if(c=='-') f=-1;
        for(;isdigit(c);c=getchar()) x=x*10+c-'0';
        return x*f;
    }
    
    inline void addedge(int u,int v,int w,int c){
        to[++cnt]=v,fl[cnt]=w,cst[cnt]=c;
        nxt[cnt]=hd[u],hd[u]=cnt;
    }
    inline bool spfa(int ed){
        queue<int> q;
        memset(dis,127,sizeof(dis));
        memset(inq,0,sizeof(inq));
        dis[1]=0,inq[1]=1,q.push(1);
        while(!q.empty()){
            int u=q.front();
            q.pop(),inq[u]=0;
            for(int i=hd[u];i;i=nxt[i]){
                int v=to[i],w=fl[i],c=cst[i];
                if(w>0 && dis[v]>dis[u]+c){
                    dis[v]=dis[u]+c;
                    if(!inq[v]) q.push(v),inq[v]=1;
                }
            }
        }
        return dis[ed]<=2e9;
    }
    inline int dfs(int u,int flow,int ed){
        if(u==ed) return flow;
        vis[u]=1; int sum=0;
        for(int i=hd[u];i;i=nxt[i]){
            int v=to[i],w=fl[i],c=cst[i];
            if(!vis[v] && w>0 && dis[v]==dis[u]+c){
                int f=dfs(v,min(flow,w),ed);
                sum+=f,cost+=f*c;
                flow-=f,fl[i]-=f,fl[i^1]+=f;
                if(!flow) break;
            }
        }
        if(!sum) dis[u]=inf;
        return sum;
    }
    
    inline int Dinic(){
        memset(hd,0,sizeof(hd)),cnt=1;
        for(int i=1;i<=m;i++){
            addedge(E[i].u,E[i].v,E[i].c,0);
            addedge(E[i].v,E[i].u,0,0);
        }
        int ans=0; 
        while(spfa(n)){
            memset(vis,0,sizeof(vis));
            ans+=dfs(1,inf,n);
        }
        return ans;
    }
    
    inline int MCMF(int res){
        for(int i=1;i<=m;i++){
            addedge(E[i].u,E[i].v,inf,E[i].w);
            addedge(E[i].v,E[i].u,0,-E[i].w);
        }
        addedge(n,n+1,k,0);
        int ans=0; 
        while(spfa(n+1)){
            memset(vis,0,sizeof(vis));
            ans+=dfs(1,inf,n+1);
        }
        return cost;
    }
    
    int main(){
        n=read(),m=read(),k=read();
        for(int i=1;i<=m;i++)
            E[i].u=read(),E[i].v=read(),E[i].c=read(),E[i].w=read();
        int res=Dinic();
        printf("%d %d
    ",res,MCMF(res));
        return 0;
    }
    网络扩容
  • 相关阅读:
    一个秒杀系统的设计
    2018年终总结-从我所在的团队回首一年技术变迁
    温习LOGO语言
    微信公众平台配置-笔记
    Spring mongotemplate使用
    三种方法实现MNIST 手写数字识别
    Python 实现0-1背包
    Python 实现快速排序和随机快速排序
    Spring+SpringMVC+Mybatis搭建的网站的处理流程总结
    Mybatis功能架构及执行流程
  • 原文地址:https://www.cnblogs.com/YSFAC/p/13211857.html
Copyright © 2020-2023  润新知