zoukankan      html  css  js  c++  java
  • bzoj1834: [ZJOI2010]network 网络扩容 费用流

    bzoj1834
    给定一张有向图,每条边都有一个容量C和一个扩容费用W。这里扩容费用是指将容量扩大1所需的费用。
    求:
    1、在不扩容的情况下,1到N的最大流;
    2、将1到N的最大流增加K所需的最小扩容费用。
    Input
    第一行包含三个整数N,M,K,表示有向图的点数、边数以及所需要增加的流量。
    接下来的M行每行包含四个整数u,v,C,W,表示一条从u到v,容量为C,扩容费用为W的边。
    N<=1000,M<=5000,K<=10
    Output
    输出文件一行包含两个整数,分别表示问题1和问题2的答案。
    先按每条费用为0,容量为c跑费用流求最大流量,然后对原图中每条边建一条容量inf,费用为w的边,新建超级源和1连边,容量k,费用0,
    因为要保证流量增加k,而且原图中的边是没有费用的,而只要增加 了费用,流量一定够,所以设成inf

    /**************************************************************
        Problem: 1834
        User: walfy
        Language: C++
        Result: Accepted
        Time:112 ms
        Memory:2720 kb
    ****************************************************************/
     
    //#pragma comment(linker, "/stack:200000000")
    //#pragma GCC optimize("Ofast,no-stack-protector")
    //#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
    //#pragma GCC optimize("unroll-loops")
    #include<bits/stdc++.h>
    #define fi first
    #define se second
    #define mp make_pair
    #define pb push_back
    #define pi acos(-1.0)
    #define ll long long
    #define vi vector<int>
    #define mod 1000000007
    #define ld long double
    #define C 0.5772156649
    #define ls l,m,rt<<1
    #define rs m+1,r,rt<<1|1
    #define pil pair<int,ll>
    #define pli pair<ll,int>
    #define pii pair<int,int>
    #define cd complex<double>
    #define ull unsigned long long
    #define base 1000000000000000000
    #define fio ios::sync_with_stdio(false);cin.tie(0)
     
    using namespace std;
     
    const double eps=1e-6;
    const int N=20000+10,maxn=50000+10,inf=0x3f3f3f3f,INF=0x3f3f3f3f3f3f3f3f;
     
    struct edge{
        int to,Next,c;
        int cost;
    }e[maxn];
    int cnt,head[N];
    int s,t;
    int dis[N],pre[N],path[N];
    bool vis[N];
    void add(int u,int v,int c,int cost)
    {
        e[cnt].to=v;
        e[cnt].c=c;
        e[cnt].cost=cost;
        e[cnt].Next=head[u];
        head[u]=cnt++;
        e[cnt].to=u;
        e[cnt].c=0;
        e[cnt].cost=-cost;
        e[cnt].Next=head[v];
        head[v]=cnt++;
    }
    bool spfa()
    {
        memset(pre,-1,sizeof pre);
        memset(dis,inf,sizeof dis);
        memset(vis,0,sizeof vis);
        dis[s]=0;
        vis[s]=1;
        queue<int>q;
        q.push(s);
        while(!q.empty())
        {
            int x=q.front();
            q.pop();
            vis[x]=0;
            for(int i=head[x];~i;i=e[i].Next)
            {
                int te=e[i].to;
                if(e[i].c>0&&dis[x]+e[i].cost<dis[te])
                {
                    dis[te]=dis[x]+e[i].cost;
                    pre[te]=x;
                    path[te]=i;
                    if(!vis[te])q.push(te),vis[te]=1;
                }
            }
        }
        return pre[t]!=-1;
    }
    int maxflow()
    {
        int flow=0;
        while(spfa())
        {
            int f=inf;
            for(int i=t;i!=s;i=pre[i])
                if(e[path[i]].c<f)
                   f=e[path[i]].c;
            flow+=f;
            for(int i=t;i!=s;i=pre[i])
            {
                e[path[i]].c-=f;
                e[path[i]^1].c+=f;
            }
        }
        return flow;
    }
    int mincostmaxflow()
    {
        int cost=0,flow=0;
        while(spfa())
        {
            int f=inf;
            for(int i=t;i!=s;i=pre[i])
                if(e[path[i]].c<f)
                   f=e[path[i]].c;
            flow+=f;
            cost+=dis[t]*f;
            for(int i=t;i!=s;i=pre[i])
            {
                e[path[i]].c-=f;
                e[path[i]^1].c+=f;
            }
        }
        return cost;
    }
    void init()
    {
        memset(head,-1,sizeof head);
        cnt=0;
    }
    struct node{int u,v,c,w;}te[N];
    int main()
    {
        int n,m,k;
        scanf("%d%d%d",&n,&m,&k);
        init();
        for(int i=0;i<m;i++)
        {
            int u,v,c,w;
            scanf("%d%d%d%d",&u,&v,&c,&w);
            add(u,v,c,0);
            te[i]={u,v,c,w};
        }
        s=1,t=n;
        printf("%d ",maxflow());
        for(int i=0;i<m;i++)
            add(te[i].u,te[i].v,inf,te[i].w);
        s=n+1;add(s,1,k,0);
        printf("%d
    ",mincostmaxflow());
        return 0;
    }
    /********************
     
    ********************/
    
  • 相关阅读:
    记录Integer比较问题
    代码中获取git输出
    python open mode
    elasticsearch Unrecognized VM option 'UseParNewGC'
    应用商店显示无法加载页面 请稍后重试
    deep learning with python前五章笔记
    QWeb2: Template 'systray_odoo_referral.gift_icon' not found
    wifi scapy
    struct.pack, struct.unpack详解
    python f-string
  • 原文地址:https://www.cnblogs.com/acjiumeng/p/9302117.html
Copyright © 2011-2022 走看看