[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;
}

(=´ω`=)

时间: 2024-10-17 08:21:50

[zjoi2010]网络扩容的相关文章

luogu P2604 [ZJOI2010]网络扩容 |费用流

题目描述 给定一张有向图,每条边都有一个容量\(C\)和一个扩容费用\(W\).这里扩容费用是指将容量扩大1所需的费用.求: 1. 在不扩容的情况下,1到N的最大流: 2. 将1到N的最大流增加K所需的最小扩容费用. 输入格式 输入文件的第一行包含三个整数\(N,M,K\),表示有向图的点数.边数以及所需要增加的流量. 接下来的M行每行包含四个整数\(u,v,C,W\),表示一条从u到v,容量为C,扩容费用为W的边. 输出格式 输出文件一行包含两个整数,分别表示问题1和问题2的答案. 利用残余网

[ZJOI2010]网络扩容 (最大流 + 费用流)

题目描述 给定一张有向图,每条边都有一个容量C和一个扩容费用W.这里扩容费用是指将容量扩大1所需的费用.求: 1. 在不扩容的情况下,1到N的最大流: 2. 将1到N的最大流增加K所需的最小扩容费用. 输入输出格式 输入格式: 输入文件的第一行包含三个整数N,M,K,表示有向图的点数.边数以及所需要增加的流量. 接下来的M行每行包含四个整数u,v,C,W,表示一条从u到v,容量为C,扩容费用为W的边. 输出格式: 输出文件一行包含两个整数,分别表示问题1和问题2的答案. 输入输出样例 输入样例#

洛谷 P2604 [ZJOI2010]网络扩容

题目描述 给定一张有向图,每条边都有一个容量C和一个扩容费用W.这里扩容费用是指将容量扩大1所需的费用.求: 1. 在不扩容的情况下,1到N的最大流: 2. 将1到N的最大流增加K所需的最小扩容费用. 输入输出格式 输入格式: 输入文件的第一行包含三个整数N,M,K,表示有向图的点数.边数以及所需要增加的流量. 接下来的M行每行包含四个整数u,v,C,W,表示一条从u到v,容量为C,扩容费用为W的边. 输出格式: 输出文件一行包含两个整数,分别表示问题1和问题2的答案. 输入输出样例 输入样例#

bzoj1834 ZJOI2010网络扩容(费用流)

给定一张有向图,每条边都有一个容量C和一个扩容费用W.这里扩容费用是指将容量扩大1所需的费用. 求: 1.在不扩容的情况下,1到N的最大流: 2.将1到N的最大流增加K所需的最小扩容费用. 其中\(n \le 1000,m \le 5000,k \le 10\) 网络流题,复杂度都是没用的了.... 第一问就是一个裸的最大流 现在我们考虑第二问QwQ 最小扩容费用,我们是不是可以对于原图中的\(u->v\)的边,添加一条\(u->v\),流量为\(inf\),费用为\(w\)的边,这样就可以实

【[ZJOI2010]网络扩容】

题目 第一问直接板子敲上去 第二问并不明白直接在残量网络上加边的神仙做法 非常显然我们需要让流量加\(k\),那么我们就使得网络里的总流量为\(maxf+k\),\(maxf\)是第一问求出来的最大流 所以搞一个超级源点,向\(1\)连一条流量是\(maxf+k\)费用是\(0\)的边,之后在原来的图的基础上再给每条边加一条流量为\(inf\),费用为相应费用的边 这样让它自己在里面流就必然会流出来\(maxf+k\)的流量 求出最小费用就好了 代码 #include<algorithm> #

p2604 [ZJOI2010]网络扩容

传送门 分析 第一问就是最大流 第二问用一个源点向1连一条流量为第一问答案+k的边然后跑费用流即可 代码 #include<iostream> #include<cstdio> #include<cstring> #include<string> #include<algorithm> #include<cctype> #include<cmath> #include<cstdlib> #include<

bzoj1834: [ZJOI2010]network 网络扩容

努力看了很久样例一直过不了...然后各种输出中间过程啊巴拉巴拉弄了1h,没办法了...然后突然想到啊原来的边可以用啊为什么不用...于是A了...感人肺腑 #include<cstdio> #include<cstring> #include<queue> #include<iostream> #include<algorithm> using namespace std; #define rep(i,n) for(int i=1;i<=n

bzoj 1834: [ZJOI2010]network 网络扩容 -- 最大流+费用流

1834: [ZJOI2010]network 网络扩容 Time Limit: 3 Sec  Memory Limit: 64 MB Description 给定一张有向图,每条边都有一个容量C和一个扩容费用W.这里扩容费用是指将容量扩大1所需的费用.求: 1. 在不扩容的情况下,1到N的最大流: 2. 将1到N的最大流增加K所需的最小扩容费用. Input 输入文件的第一行包含三个整数N,M,K,表示有向图的点数.边数以及所需要增加的流量. 接下来的M行每行包含四个整数u,v,C,W,表示一

C++之路进阶——网络流(网络扩容)

1362 网络扩容 省队选拔赛 时间限制: 2 s 空间限制: 128000 KB 题目等级 : 大师 Master 题目描述 Description 给定一张有向图,每条边都有一个容量C和一个扩容费用W.这里扩容费用是指将容量扩大1所需的费用.求: 1.  在不扩容的情况下,1到N的最大流: 2.  将1到N的最大流增加K所需的最小扩容费用. 输入描述 Input Description 输入文件的第一行包含三个整数N,M,K,表示有向图的点数.边数以及所需要增加的流量. 接下来的M行每行包含