【BZOJ】1834 [ZJOI2010]network 网络扩容
【算法】网络流-最大流+最小费用最大流(费用流)
【题解】
第一问跑最大流。
第二问:
原始边相当于费用为0的边,再原图(跑过最大流的图)基础上添加带费用的边,容量为k(相当于inf)。
第一问最大流使用了哪条边对第二问没有影响,因为费用流肯定优先往费用为0的边(原始边)跑。
限流k?添加超级源向1连容量k费用0的边即可。
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn=,maxm=,N=,inf=0x3f3f3f3f;
int tot=,first[maxn],d[maxn],q[maxn],cur[maxn],S,T,sum,n,m,K,u[maxm],v[maxm],w[maxm];
bool vis[maxn];
struct edge{int v,f,c,from;}e[maxm*]; void insert(int u,int v,int f,int c){
tot++;e[tot].v=v;e[tot].f=f;e[tot].c=c;e[tot].from=first[u];first[u]=tot;
tot++;e[tot].v=u;e[tot].f=;e[tot].c=-c;e[tot].from=first[v];first[v]=tot;
}
bool bfs(){
memset(d,-,sizeof(d));
int head=,tail=;q[head]=S;d[S]=;
while(head<tail){
int x=q[head++];
for(int i=first[x];i;i=e[i].from)
if(e[i].f&&d[e[i].v]==-){
d[e[i].v]=d[x]+;
q[tail++]=e[i].v;
}
}
return ~d[T];
}
int dinic(int x,int a){
if(x==T||a==)return a;
int flow=,f;
for(int& i=cur[x];i;i=e[i].from)
if(d[e[i].v]==d[x]+&&(f=dinic(e[i].v,min(e[i].f,a)))){
e[i].f-=f;e[i^].f+=f;
flow+=f;a-=f;
if(a==)break;
}
return flow;
}
int solve1(){
int ans=;
while(bfs()){
for(int i=S;i<=T;i++)cur[i]=first[i];
ans+=dinic(S,inf);
}
return ans;
}
bool spfa(){
memset(d,0x3f,sizeof(d));
int head=,tail=;q[head]=T;d[T]=;vis[T]=;
while(head!=tail){
int x=q[head++];if(head>N)head=;
for(int i=first[x];i;i=e[i].from)
if(e[i^].f&&d[x]+e[i^].c<d[e[i].v]){
d[e[i].v]=d[x]+e[i^].c;
if(!vis[e[i].v]){
if(d[e[i].v]<d[q[head]]){if(--head<)head=N;q[head]=e[i].v;}
else{q[tail++]=e[i].v;if(tail>N)tail=;}
vis[e[i].v]=;
}
}
vis[x]=;//
}
return d[S]<inf;
}
int dfs(int x,int a){
if(x==T||a==)return a;
vis[x]=;
int flow=,f;
for(int& i=cur[x];i;i=e[i].from)
if(!vis[e[i].v]&&d[e[i].v]+e[i].c==d[x]&&(f=dfs(e[i].v,min(e[i].f,a)))){
e[i].f-=f;e[i^].f+=f;
sum+=e[i].c*f;
flow+=f;a-=f;
if(a==)break;
}
vis[x]=;
return flow;
}
int solve2(){
sum=;
while(spfa()){
for(int i=S;i<=T;i++)cur[i]=first[i];
dfs(S,inf);
}
return sum;
}
int main(){
scanf("%d%d%d",&n,&m,&K);
S=;T=n;
for(int i=;i<=m;i++){
int c;
scanf("%d%d%d%d",&u[i],&v[i],&c,&w[i]);
insert(u[i],v[i],c,);
}
printf("%d ",solve1());
S=;
for(int i=;i<=m;i++)insert(u[i],v[i],K,w[i]);
insert(S,,K,);
printf("%d",solve2());
return ;
}
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn=,maxm=,N=,inf=0x3f3f3f3f;
int tot=,first[maxn],d[maxn],q[maxn],cur[maxn],S,T,sum,n,m,K,u[maxm],v[maxm],w[maxm],c[maxm];
bool vis[maxn];
struct edge{int v,f,c,from;}e[maxm*]; void insert(int u,int v,int f,int c){
tot++;e[tot].v=v;e[tot].f=f;e[tot].c=c;e[tot].from=first[u];first[u]=tot;
tot++;e[tot].v=u;e[tot].f=;e[tot].c=-c;e[tot].from=first[v];first[v]=tot;
}
bool bfs(){
memset(d,-,sizeof(d));
int head=,tail=;q[head]=S;d[S]=;
while(head<tail){
int x=q[head++];
for(int i=first[x];i;i=e[i].from)
if(e[i].f&&d[e[i].v]==-){
d[e[i].v]=d[x]+;
q[tail++]=e[i].v;
}
}
return ~d[T];
}
int dinic(int x,int a){
if(x==T||a==)return a;
int flow=,f;
for(int& i=cur[x];i;i=e[i].from)
if(d[e[i].v]==d[x]+&&(f=dinic(e[i].v,min(e[i].f,a)))){
e[i].f-=f;e[i^].f+=f;
flow+=f;a-=f;
if(a==)break;
}
return flow;
}
int solve1(){
int ans=;
while(bfs()){
for(int i=S;i<=T;i++)cur[i]=first[i];
ans+=dinic(S,inf);
}
return ans;
}
bool spfa(){
memset(d,0x3f,sizeof(d));
int head=,tail=;q[head]=T;d[T]=;vis[T]=;
while(head!=tail){
int x=q[head++];if(head>N)head=;
for(int i=first[x];i;i=e[i].from)
if(e[i^].f&&d[x]+e[i^].c<d[e[i].v]){
d[e[i].v]=d[x]+e[i^].c;
if(!vis[e[i].v]){
if(d[e[i].v]<d[q[head]]){if(--head<)head=N;q[head]=e[i].v;}
else{q[tail++]=e[i].v;if(tail>N)tail=;}
vis[e[i].v]=;
}
}
vis[x]=;//
}
return d[S]<inf;
}
int dfs(int x,int a){
if(x==T||a==)return a;
vis[x]=;
int flow=,f;
for(int& i=cur[x];i;i=e[i].from)
if(!vis[e[i].v]&&d[e[i].v]+e[i].c==d[x]&&(f=dfs(e[i].v,min(e[i].f,a)))){
e[i].f-=f;e[i^].f+=f;
sum+=e[i].c*f;
flow+=f;a-=f;
if(a==)break;
}
vis[x]=;
return flow;
}
int solve2(){
sum=;
while(spfa()){
for(int i=S;i<=T;i++)cur[i]=first[i];
dfs(S,inf);
}
return sum;
}
int main(){
scanf("%d%d%d",&n,&m,&K);
S=;T=n;
for(int i=;i<=m;i++){
scanf("%d%d%d%d",&u[i],&v[i],&c[i],&w[i]);
insert(u[i],v[i],c[i],);
}
int now=;
printf("%d ",now=solve1());
tot=;memset(first,,sizeof(first));//
for(int i=;i<=m;i++){
insert(u[i],v[i],c[i],);
insert(u[i],v[i],K,w[i]);
}
S=;
insert(S,,now+K,);
printf("%d",solve2());
return ;
}
【BZOJ】1834 [ZJOI2010]network 网络扩容的更多相关文章
- BZOJ 1834: [ZJOI2010]network 网络扩容(最大流+最小费用最大流)
第一问直接跑最大流.然后将所有边再加一次,费用为扩容费用,容量为k,再从一个超级源点连一条容量为k,费用为0的边到原源点,从原汇点连一条同样的边到超级汇点,然 后跑最小费用最大流就OK了. ---- ...
- bzoj 1834: [ZJOI2010]network 网络扩容 -- 最大流+费用流
1834: [ZJOI2010]network 网络扩容 Time Limit: 3 Sec Memory Limit: 64 MB Description 给定一张有向图,每条边都有一个容量C和一 ...
- bzoj 1834 [ZJOI2010]network 网络扩容(MCMF)
[题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=1834 [题意] 给定一个有向图,每条边有容量C,扩容费用W,问最大流和使容量增加K的最 ...
- BZOJ 1834 [ZJOI2010]network 网络扩容(费用流)
[题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=1834 [题目大意] 给定一张有向图,每条边都有一个容量C和一个扩容费用W. 这里扩容费 ...
- bzoj 1834: [ZJOI2010]network 网络扩容
#include<cstdio> #include<iostream> #include<cstring> #define M 100000 #define inf ...
- bzoj 1834: [ZJOI2010]network 网络扩容【最大流+最小费用最大流】
第一问直接跑最大流即可.建图的时候按照费用流建,费用为0. 对于第二问,在第一问dinic剩下的残量网络上建图,对原图的每条边(i,j),建(i,j,inf,cij),表示可以用c的花费增广这条路.然 ...
- BZOJ 1834: [ZJOI2010]network 网络扩容 最小费用流_最大流_残量网络
对于第一问,跑一遍最大流即可. 对于第二问,在残量网络上的两点间建立边 <u,v>,容量为无限大,费用为扩充费用. 跑一遍最小费用流即可. Code: #include <vecto ...
- BZOJ 1834: [ZJOI2010]network 网络扩容(网络流+费用流)
一看就知道是模板题= = ,不说什么了= = PS:回去搞期末了,暑假再来刷题了 CODE: #include<cstdio> #include<iostream> #incl ...
- 【BZOJ】1834: [ZJOI2010]network 网络扩容(最大流+费用流)
http://www.lydsy.com/JudgeOnline/problem.php?id=1834 我又思考人生了T_T,nd的数组开小了,一直wa,调了一个小时才发现啊!!!!!我一直以为我的 ...
随机推荐
- 03_Java基础语法_第3天(Scanner、Random、流程控制语句)_讲义
今日内容介绍 1.引用类型变量的创建及使用 2.流程控制语句之选择语句 3.流程控制语句之循环语句 4.循环高级 01创建引用类型变量公式 * A: 创建引用类型变量公式 * a: 我们要学的Scan ...
- c99标准的restrict关键字
参考自restrict restrict解释 restrict关键字出现于C99标准,wiki上的解释restrict from wiki. In the C programming language ...
- Windows连接Linux服务器中MySQL数据库-权限配置
问题描述 在Windows系统中安装了监控MySQL数据库服务器性能的工具Spotlight on MySQL,利用Spotlight连接Linux服务器中的MySQL,进行相关配置如下: 点击& ...
- SQL的拼接语句在DELPHI中怎么写
SQL 语句的拼接,关键点在于对引号的处理上. 在 delphi 的语法中,使用单引号做字符串的标志符.因此,当遇到 SQL 语句中字符串标识量编写的时候,需要用两个单引号来代替实际的引号. 举例: ...
- Kafka设计解析
Kafka剖析(一):Kafka背景及架构介绍 Kafka设计解析(二):Kafka High Availability (上) Kafka设计解析(三):Kafka High Availabilit ...
- Problem D - Non-boring sequences——Contest1004 - National Day Training Contest -- Day3
今天比赛的时候做的一个坑题.深坑啊. 题目意思是给你一个有n个数的数字序列.要你判断对于这个序列是都满足任意一个子序列都至少含有一个只出现一次的数字. 看完题目后没什么思路,一直以为要用线段树,每次删 ...
- compareTo 返回为整数 调用者比参数大;返回负数 调用者比参数小
compareTo 返回为整数 调用者比参数大;返回负数 调用者比参数小
- noip模拟题《戏》game
[问题背景] zhx 和他的妹子(们) 做游戏.[问题描述] 考虑 N 个人玩一个游戏,任意两个人之间进行一场游戏(共 N*(N-1)/2 场),且每场一定能分出胜负. ...
- 【转】实现虚拟机VMware上linux与windows互相复制与粘贴
1.点击虚拟机-->安装vm tool 2.完成后在系统桌面会出现一个tar文件,解压到tmp目录 下 3.终端cd到该文件夹下,执行./vmware-install.pl 一路回车到底.4.重 ...
- Coding and Paper Letter(四十五)
资源整理. 1 Coding: 1.Python库gempy,一种基于Python的开源三维结构地质建模软件,它允许从界面和方向数据隐式(即自动)创建复杂的地质模型. 它还支持随机建模以解决参数和模型 ...