zoukankan      html  css  js  c++  java
  • [zjoi2010]网络扩容

    描述 Description 

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

    1、 在不扩容的情况下,1到N的最大流;

    2、 将1到N的最大流增加K所需的最小扩容费用。 

    输入格式 Input Format
    输入文件的第一行包含三个整数N,M,K,表示有向图的点数、边数以及所需要增加的流量。

      接下来的M行每行包含四个整数u,v,C,W,表示一条从u到v,容量为C,扩容费用为W的边。 

    输出格式 Output Format
    输出文件一行包含两个整数,分别表示问题1和问题2的答案。 

    样例输入 Sample Input
    5 8 2
    1 2 5 8
    2 5 9 9
    5 1 6 2
    5 1 1 8
    1 2 8 7
    2 5 4 9
    1 2 1 1
    1 4 2 1 

    样例输出 Sample Output
    13 19 

    时间限制 Time Limitation
    1s 

    注释 Hint
    30%的数据中,N<=100

    100%的数据中,N<=1000,M<=5000,K<=10

    来源 Source
    zjoi2010 

          今天把oj上费用流的题写完了,真心的毒哇...........不仅建图的能力提升了,代码细节.........不说了

          思路:这个题就先建将u到v的这一条边费用为0,容量为c建一条边。然后在在u到v建一条费用为W,容量为正无穷的边。然后跑一边最大流,之后再在0到1连一条容量为k费用为0的边,然后再跑一边费用流就好了。然后写完之后莫名其妙的徐王......后来发现自己又智障的打错了变量名_(:з」∠)_ 

    代码如下:

    #include<iostream>
    #include<cstdio>
    #include<cmath>
    #include<algorithm>
    #include<cstring>
    #define INF 0x7fffffff
    using namespace std;
    inline int read()
    {
        int x=0,f=1;
        char ch=getchar();
        while(ch>'9'||ch<'0')
        {
            if(ch=='-')
                f=-1;
            ch=getchar();
        }
        while(ch>='0'&&ch<='9')
        {
            x=x*10+ch-'0';
            ch=getchar();
        }
        return x*f;
    }
    struct shadow
    {
        int y,next,v,c,rev;
    }a[50000];
    int lin[500000],len=1,s=0,t;
    void insert(int x,int y,int v,int c)
    {
        a[++len].y=y;a[len].next=lin[x];a[len].v=v;lin[x]=len;a[len].rev=len+1;a[len].c=c;
        a[++len].y=x;a[len].next=lin[y];a[len].v=0;lin[y]=len;a[len].rev=len-1;a[len].c=-c;
    }
    int l[50000],q[50000];
    int n,m,k;
    bool make_level()
    {
        int head=0,tail=1;
        memset(l,-1,sizeof(l));
        q[1]=1;l[1]=0;
        while(head<tail)
        {
            int tn=q[++head];
            for(int i=lin[tn];i;i=a[i].next)
            {
                if(a[i].v&&l[a[i].y]<0&&!a[i].c)
                {
                    q[++tail]=a[i].y;
                    l[a[i].y]=l[tn]+1;
                }
            }
        }
        return l[n]>=0;
    }
    int MAX(int k,int flow)
    {
        if(k==n)
            return flow;
        int maxflow=0,d=0;
        for(int i=lin[k];i&&maxflow<flow;i=a[i].next)
        {
            if(l[a[i].y]==l[k]+1&&a[i].v&&!a[i].c)
            {
                if(d=MAX(a[i].y,min(flow-maxflow,a[i].v)))
                {
                    maxflow+=d;
                    a[i].v-=d;
                    a[a[i].rev].v+=d;
                }
            }
        }
        if(!maxflow)
            l[k]=-1;
        return maxflow;
    }
    int ans=0;
    void Dinic()
    {
        int d;
        while(make_level())
            while(d=MAX(1,INF))
                ans+=d;
        cout<<ans<<endl;
    }
    int w[50000],dis[50000],pre[50000],pro[50000];
    bool vis[50000];
    bool SPFA()
    {
        memset(vis,0,sizeof(vis));
        memset(dis,10,sizeof(dis));
        dis[s]=0;vis[s]=1;q[0]=s;
        int head=0,tail=1;
        while(head<tail)
        {
            int tn=q[head++];
            vis[tn]=0;
            for(int i=lin[tn];i;i=a[i].next)
            {
                int tmp=a[i].y;
                if(dis[tn]+a[i].c<dis[tmp]&&a[i].v>0)
                {
                    dis[tmp]=dis[tn]+a[i].c;
                    if(!vis[tmp])
                    {
                        vis[tmp]=1;
                        q[tail++]=tmp;
                    }
                    pre[tmp]=tn;
                    pro[tmp]=i;
                }
            }
        }
        return dis[n]!=dis[n+1];
    }
    void agu()
    {
        int x=0x7fffffff;
        for(int i=n;i;i=pre[i])
            x=min(x,a[pro[i]].v);
        for(int i=n;i;i=pre[i])
        {
            a[pro[i]].v-=x;
            a[a[pro[i]].rev].v+=x;
        }
        ans+=x*dis[n];
    }
    int Q[50000],W[50000],E[50000],R[50000];
    int main()
    {
        n=read();m=read();k=read();
        for(int i=1;i<=m;i++)
        {
            Q[i]=read();W[i]=read();E[i]=read();R[i]=read();
            insert(Q[i],W[i],E[i],0);
            insert(Q[i],W[i],INF,R[i]);
        }
        Dinic();
        insert(0,1,k,0);
        ans=0;
        while(SPFA())
            agu();
        cout<<ans<<endl;
        return 0;
    }
    (=´ω`=)
  • 相关阅读:
    mysql实战45讲
    goland破解
    主从复制系列C
    主从复制系列B
    主从复制系列A
    sshd配置文件详解
    MySQL源码 数据结构array
    MySQL源码 information_schema新增表
    MySQL5.6 基于db的并行复制
    mysql 限制并发select patch
  • 原文地址:https://www.cnblogs.com/lcyhaha/p/7559616.html
Copyright © 2011-2022 走看看