题面

传送门

思路

第一问:无脑网络流跑一波

第二问:

先考虑一个贪心的结论:扩容出来的扩容流量一定要跑满

证明显然

因此我们可以把扩容费用可以换个角度思考,变成增加一点流量,花费W的费用

这样,我们就得到了一个最小费用流的模型

只要在原图基础上,对于每个原图边,加一条费用为W,无限容量的边,而原图中的所有边费用为0,就可以模拟原题需要的情况了

最后一个问题:流量增加限制K怎么处理?

我们虽然可以用spfa的费用流,一次一次增加,直到K,但是这样也太慢chou了吧?

不怕,我们加一个n+1号点,作为第二问的费用流汇点,在n到n+1之间连一条边,费用为0,流量为第一问的最大流流量加上K

注意:上述算法是对于第二问建一个新图来跑的,对于在残量网络上瞎搞的方法,由于本人水平有限,并无法很好地证明正确性

我的算法,时间复杂度大概会多一个$O\left(m\right)$,再加上一点常数

同时因为我是zkw费用流实现的最大流,所以大概稍慢....?

其实应该是一样的吧!

Code:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define inf 1e9
using namespace std;
inline int read(){
int re=0,flag=1;char ch=getchar();
while(ch>'9'||ch<'0'){
if(ch=='-') flag=-1;
ch=getchar();
}
while(ch>='0'&&ch<='9') re=(re<<1)+(re<<3)+ch-'0',ch=getchar();
return re*flag;
}
int n,m,cnt=-1,ans,K,first[1010],dis[1010],vis[1010];
struct edge{
int to,next,w,cap;
}a[25010];
inline void add(int u,int v,int w,int cap){
a[++cnt]=(edge){v,first[u],w,cap};first[u]=cnt;
a[++cnt]=(edge){u,first[v],-w,0};first[v]=cnt;
}
bool spfa(int s,int t){
int q[5010],head=0,tail=1,u,v,w,i;
memset(dis,-1,sizeof(dis));memset(vis,0,sizeof(vis));
q[0]=t;dis[t]=0;vis[t]=1;
while(head<tail){
u=q[head++];vis[u]=0;
for(i=first[u];~i;i=a[i].next){
v=a[i].to;w=a[i].w;
if(a[i^1].cap&&((dis[v]==-1)||(dis[v]>dis[u]-w))){
dis[v]=dis[u]-w;
if(!vis[v]) q[tail++]=v,vis[v]=1;
}
}
}
return ~dis[s];
}
int dfs(int u,int t,int limit){
if(u==t){vis[t]=1;return limit;}
if(!limit){vis[u]=1;return 0;}
int i,v,f,flow=0,w;vis[u]=1;
for(i=first[u];~i;i=a[i].next){
v=a[i].to;w=a[i].w;
if((dis[v]==dis[u]-w)&&(!vis[v])&&a[i].cap){
f=dfs(v,t,min(limit,a[i].cap));if(!f) continue;
a[i].cap-=f;a[i^1].cap+=f;
flow+=f;limit-=f;ans+=a[i].w*f;
if(!limit) return flow;
}
}
return flow;
}
int zkw(int s,int t){//zkw费用流
int re=0;
while(spfa(s,t)){
vis[t]=1;
while(vis[t]){
memset(vis,0,sizeof(vis));
re+=dfs(s,t,inf);
//cout<<"cur re="<<re<<"\n";
}
}
return re;
}
int cost[5010],u[5010],v[5010],cap[5010];
int main(){
memset(first,-1,sizeof(first));
int i,maxflow;
n=read();m=read();K=read();
for(i=1;i<=m;i++){
u[i]=read();v[i]=read();cap[i]=read();cost[i]=read();
add(u[i],v[i],0,cap[i]);
}
printf("%d ",maxflow=zkw(1,n));//maxflow要记录下来,后面有用
memset(first,-1,sizeof(first));memset(a,0,sizeof(a));cnt=-1;//清理原图,重新建图
for(i=1;i<=m;i++){
add(u[i],v[i],0,cap[i]);
add(u[i],v[i],cost[i],inf);
}
add(n,n+1,0,maxflow+K);
zkw(1,n+1);
printf("%d",ans);
}

[ZJOI2010][bzoj1834] 网络扩容 [费用流]的更多相关文章

  1. bzoj1834: [ZJOI2010]network 网络扩容 费用流

    bzoj1834 给定一张有向图,每条边都有一个容量C和一个扩容费用W.这里扩容费用是指将容量扩大1所需的费用. 求: 1.在不扩容的情况下,1到N的最大流: 2.将1到N的最大流增加K所需的最小扩容 ...

  2. [BZOJ1834][ZJOI2010]network 网络扩容 最大流+费用流

    1834: [ZJOI2010]network 网络扩容 Time Limit: 3 Sec  Memory Limit: 64 MB Submit: 3330  Solved: 1739 [Subm ...

  3. 【BZOJ1834】[ZJOI2010]network 网络扩容 最大流+最小费用流

    [BZOJ1834][ZJOI2010]network 网络扩容 Description 给定一张有向图,每条边都有一个容量C和一个扩容费用W.这里扩容费用是指将容量扩大1所需的费用.求: 1. 在不 ...

  4. BZOJ 1834: [ZJOI2010]network 网络扩容(最大流+最小费用最大流)

    第一问直接跑最大流.然后将所有边再加一次,费用为扩容费用,容量为k,再从一个超级源点连一条容量为k,费用为0的边到原源点,从原汇点连一条同样的边到超级汇点,然  后跑最小费用最大流就OK了. ---- ...

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

    1834: [ZJOI2010]network 网络扩容 Time Limit: 3 Sec  Memory Limit: 64 MB Description 给定一张有向图,每条边都有一个容量C和一 ...

  6. BZOJ1834 [ZJOI2010]network 网络扩容 【最大流,费用流】

    1834: [ZJOI2010]network 网络扩容 Time Limit: 3 Sec  Memory Limit: 64 MB Submit: 3394  Solved: 1774 [Subm ...

  7. BZOJ-1834 网络扩容 最小费用最大流+最大流+乱搞

    1834: [ZJOI2010]network 网络扩容 Time Limit: 3 Sec Memory Limit: 64 MB Submit: 2269 Solved: 1136 [Submit ...

  8. BZOJ_1834_[ZJOI2010]network 网络扩容_费用流

    BZOJ_1834_[ZJOI2010]network 网络扩容_费用流 题意: 给定一张有向图,每条边都有一个容量C和一个扩容费用W.这里扩容费用是指将容量扩大1所需的费用. 求:  1.在不扩容的 ...

  9. bzoj1834: [ZJOI2010]network 网络扩容

    努力看了很久样例一直过不了...然后各种输出中间过程啊巴拉巴拉弄了1h,没办法了...然后突然想到啊原来的边可以用啊为什么不用...于是A了...感人肺腑 #include<cstdio> ...

随机推荐

  1. 解决ndk编译lua时遇到 undefined reference to '__srget'的问题

    今天用ndk r10d版本编译lua时,遇到几个错误,提示没有找到__srget 没有定义,于是看了国外的大神的解决方法, 是因为ndk在r10c之后的版本已经将getc函数屏蔽了,所以导致编译器找不 ...

  2. 博学谷-数据分析matplotlib

    博学谷-数据分析 python数学学科的基础 机器学习课程的基础 1.1 介绍 1.2 jupyter和conda 1.3 matplotlib from matplotlib import pypl ...

  3. Vue源码学习二 ———— Vue原型对象包装

    Vue原型对象的包装 在Vue官网直接通过 script 标签导入的 Vue包是 umd模块的形式.在使用前都通过 new Vue({}).记录一下 Vue构造函数的包装. 在 src/core/in ...

  4. C/C++ 程序基础 (一)基本语法

    域操作符: C++ 支持通过域操作符访问全局变量,C不支持(识别为重定义) ++i和i++的效率分析: 内置类型,无区别 自定义数据类型,++i可以返回引用,i++只能返回对象值(拷贝开销) 浮点数与 ...

  5. 谈谈Integer中的静态类IntegerCache

            学习的本质就是一个赋值的过程,用新知识来覆盖你的旧知识或者无知(null).掌握知识是自己的, 分享知识,才能帮助更多的人,创造更大的价值.学贵以恒,以此自勉,与君共享.----曦阳X ...

  6. 2 > 1 and 3 < 4 or 4 > 5 and 2 < 1

    a,b,c,d,e=1,2,3,4,5 m = b >a and c < d n = d > e and b < a y = m or n info = ''' m is %s ...

  7. python标准模块

    sys模块 这是一个跟python解释器关系密切的标准库.它提供了一些和python解释器操作密切的属性和函数. sys中常用的函数和属性: sys.argv: sys.argv是专门用来向pytho ...

  8. STM32位带操作

    STM32的位带操作是基于cortex内核自带的,而不是st公司独创.基本的思路就是用一个32位的地址空间访问一个bit,因为stm32只支持32位数据的读取,不像51单片机一样,是可以单独对一位操作 ...

  9. Codeforces Round #459 (Div. 2):B. Radio Station

    B. Radio Station time limit per test2 seconds memory limit per test256 megabytes Problem Dsecription ...

  10. utf8和utf8mb4区别

    原文链接 一.简介 MySQL在5.5.3之后增加了这个utf8mb4的编码,mb4就是most bytes 4的意思,专门用来兼容四字节的unicode.好在utf8mb4是utf8的超集,除了将编 ...