p2604 [ZJOI2010]网络扩容

传送门

分析

第一问就是最大流

第二问用一个源点向1连一条流量为第一问答案+k的边然后跑费用流即可

代码

#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
#include<cctype>
#include<cmath>
#include<cstdlib>
#include<queue>
#include<ctime>
#include<vector>
#include<set>
#include<map>
#include<stack>
using namespace std;
const int inf = 1e9+7;
int n,m,k;
int s,t,Ans,now,sum;
int head[300100],w[300100],c[300100],nxt[300100],to[300100];
int fm[300100],ano[300100],S;
inline void add(int x,int y,int z,int cost){
    nxt[++S]=head[x];head[x]=S;to[S]=y;w[S]=z;c[S]=cost;fm[S]=x;
    nxt[++S]=head[y];head[y]=S;to[S]=x;w[S]=0;c[S]=-cost;fm[S]=y;
    ano[S]=S-1;ano[S-1]=S;
}
inline int work(int x){
    int i,j,k=0;
    for(i=2;i<=sqrt(x);i++)
      while(x%i==0)x/=i,k++;
    if(x>1)k++;
    return k;
}
queue<int>q;
int iq[100100],nf[100100],la[100100],d[100100];
inline void go(){
    int i,j,k;
    la[s]=0;
    while(1){
      for(i=1;i<=t;i++)d[i]=inf;
      q.push(s);
      d[s]=0,nf[s]=inf,iq[s]=1;
      while(!q.empty()){
          int u=q.front();
          q.pop(),iq[u]=0;
          for(i=head[u];i;i=nxt[i])
            if(w[i]&&d[to[i]]>d[u]+c[i]){
              d[to[i]]=d[u]+c[i];
              la[to[i]]=i;
              nf[to[i]]=min(w[i],nf[u]);
              if(!iq[to[i]]){
                q.push(to[i]);
                iq[to[i]]=1;
              }
            }
      }
      int be=now,ans=Ans,i=la[t];
      if(!nf[t]||d[t]==inf)return;
      while(i){
          w[i]-=nf[t];
          w[ano[i]]+=nf[t];
          now+=nf[t]*c[i];
          i=la[fm[i]];
      }
      Ans+=nf[t];
    }
}
int a[11000],b[11000],C[11000],D[11000];
signed main(){
    int i,j;
    scanf("%d%d%d",&n,&m,&k);
    s=1,t=n;
    for(i=1;i<=m;i++){
      scanf("%d%d%d%d",&a[i],&b[i],&C[i],&D[i]);
      add(a[i],b[i],C[i],0);
    }
    go();
    printf("%d ",Ans);
    memset(head,0,sizeof(head));
    S=0;
    for(i=1;i<=m;i++)add(a[i],b[i],C[i],0),add(a[i],b[i],inf,D[i]);
    s=n+1;
    add(s,1,Ans+k,0);
    now=Ans=0;
    go();
    printf("%d\n",now);
    return 0;
}

原文地址:https://www.cnblogs.com/yzxverygood/p/10356739.html

时间: 2024-10-06 10:22:17

p2604 [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的答案. 利用残余网

洛谷 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]网络扩容

描述 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 输出文件一行包含两个整数

[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> #

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行每行包含