BZOJ 1834: [ZJOI2010]network 网络扩容 最小费用流_最大流_残量网络
对于第一问,跑一遍最大流即可.
对于第二问,在残量网络上的两点间建立边 <u,v>,容量为无限大,费用为扩充费用.
跑一遍最小费用流即可.
Code:
#include <vector>
#include <cstdio>
#include <queue>
#include <algorithm>
#include <cstring>
#define setIO(s) freopen(s".in","r",stdin)
#define inf 100000000
#define maxn 100000
#define ll long long
using namespace std;
struct Edges{
int u,v,c,w;
}EDGE[maxn];
int n,m,k,s,t;
struct Edge{
int from,to,cap,cost;
Edge(int u,int v,int c,int f) : from(u),to(v),cap(c),cost(f){}
};
vector<int>G[maxn];
vector<Edge>edges;
void addedge(int u,int v,int c,int f){
edges.push_back(Edge(u,v,c,f));
edges.push_back(Edge(v,u,0,-f));
int o = edges.size();
G[u].push_back(o - 2);
G[v].push_back(o - 1);
}
namespace Dinic{
int d[maxn],vis[maxn];
queue<int>Q;
int BFS(){
memset(vis,0,sizeof(vis));
vis[s] = 1,d[s] = 0; Q.push(s);
while(!Q.empty()){
int u = Q.front(); Q.pop();
int sz = G[u].size();
for(int i=0;i<sz;++i) {
Edge r = edges[G[u][i]];
if(!vis[r.to] && r.cap > 0) {
d[r.to] = d[u] + 1;
vis[r.to] = 1;
Q.push(r.to);
}
}
}
return vis[t];
}
int current[maxn];
int DFS(int x,int cur){
if(x==t) return cur;
int flow=0,f;
int sz = G[x].size();
for(int i=current[x];i<sz;++i) {
int u = G[x][i];
Edge r = edges[u];
if(d[r.to] == d[x] + 1 && r.cap > 0){
f = DFS(r.to,min(cur,r.cap));
if(f > 0) {
flow += f;
cur -= f;
edges[u].cap -= f;
edges[u^1].cap += f;
}
}
if(cur==0) break;
}
return flow;
}
int maxflow(){
int flow=0;
while(BFS()){
memset(current,0,sizeof(current));
flow += DFS(s,inf);
}
return flow;
}
};
namespace MCMF{
queue<int>Q;
int d[maxn],inq[maxn];
int flow2[maxn],a[maxn];
long long ans;
int SPFA(){
for(int i=0;i<maxn;++i) d[i] = flow2[i] = inf;
memset(inq,0,sizeof(inq));
inq[s] = 1; d[s] = 0;
Q.push(s);
while(!Q.empty()){
int u=Q.front();Q.pop(); inq[u] = 0;
int sz = G[u].size();
for(int i=0;i<sz;++i) {
Edge r = edges[G[u][i]];
if(r.cap > 0 && d[r.to] > d[u] + r.cost) {
d[r.to] = d[u] + r.cost;
a[r.to] = G[u][i];
flow2[r.to] = min(flow2[u],r.cap);
if(!inq[r.to]) {
inq[r.to] = 1;
Q.push(r.to);
}
}
}
}
if(flow2[t] == inf) return 0;
int f = flow2[t];
edges[a[t]].cap -= f, edges[a[t] ^ 1].cap += f;
int u = edges[a[t]].from;
while(u != s){
edges[a[u]].cap -= f;
edges[a[u]^1].cap += f;
u = edges[a[u]].from;
}
ans += (ll)(d[t] * f);
return 1;
}
long long getcost(){
while(SPFA());
return ans;
}
};
int main(){
//setIO("input");
scanf("%d%d%d",&n,&m,&k);
s = 1, t = n;
for(int i = 1;i <= m; ++i) scanf("%d%d%d%d",&EDGE[i].u,&EDGE[i].v,&EDGE[i].c,&EDGE[i].w);
for(int i = 1;i <= m; ++i)
addedge(EDGE[i].u,EDGE[i].v,EDGE[i].c,0);
printf("%d ",Dinic::maxflow());
for(int i = 1;i <= m; ++i)
addedge(EDGE[i].u,EDGE[i].v,inf,EDGE[i].w);
s = 0 , t = n + 1;
addedge(s,1,k,0);
addedge(n,n+1,k,0);
printf("%lld",MCMF::getcost());
return 0;
}
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 网络扩容【最大流+最小费用最大流】
第一问直接跑最大流即可.建图的时候按照费用流建,费用为0. 对于第二问,在第一问dinic剩下的残量网络上建图,对原图的每条边(i,j),建(i,j,inf,cij),表示可以用c的花费增广这条路.然 ...
- 最小割最大流定理&残量网络的性质
最小割最大流定理的内容: 对于一个网络流图 $G=(V,E)$,其中有源点和汇点,那么下面三个条件是等价的: 流$f$是图$G$的最大流 残量网络$G_f$不存在增广路 对于$G$的某一个割$(S,T ...
- 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 网络扩容(网络流+费用流)
一看就知道是模板题= = ,不说什么了= = PS:回去搞期末了,暑假再来刷题了 CODE: #include<cstdio> #include<iostream> #incl ...
- BZOJ 1834 ZJOI2010 network 网络扩展 Dinic+EK费用流
标题效果:给定一个n积分m无向图边,每一方有一个扩展的成本c.代表扩张1费用的交通,寻求最大流量和扩大的最大流量k最小成本 第一问直接运行的最大流量 第二个问题将是连接到一个流的末端每个边缘的起点是正 ...
随机推荐
- vc++元文件的保存,保存图形,重绘图形
1, CMateFileDC 可以用来多次打开自己的画布,这个元文件包含许多接口的命令 当绘制好之后可以用来播放元文件 首先,创建一个CMateFileDC的元文件对象 然后调用Create原函数,创 ...
- 路飞学城Python-Day181
Evernote Export Nginx默认网站 当Nginx配置文件中有且仅有一个Server的时候,该Server就被Nginx认为是默认网站,所有发给Nginx服务器80端口的数据都会默认给s ...
- input type=”file“ change事件只执行一次的问题
js解决办法 HTML:<input id="file",type="file" onchange="upload()" /> ...
- 如何分页爬取数据--beautisoup
'''本次爬取讲历史网站'''#!usr/bin/env python#-*- coding:utf-8 _*-"""@author:Hurrican@file: 分页爬 ...
- JavaScript进阶【三】JavaScript面向对象的基础知识复习
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- nyoj8-一种排序
一种排序 时间限制:3000 ms | 内存限制:65535 KB 难度:3 描述 现在有很多长方形,每一个长方形都有一个编号,这个编号可以重复:还知道这个长方形的宽和长,编号.长.宽都是整数:现 ...
- Linux 中常用的基础命令二
1.Linux文件分层结构 FHS:Linux有一个组织叫LSB定义的Linux发行版基础目录名称命名法则及功用规定,这种标准叫FHS文件系统层级标准./bin 存放可执行的二进制程序,管理员和 ...
- 《代码敲不队》第八次团队作业:Alpha冲刺 第一天
项目 内容 这个作业属于哪个课程 任课教师博客主页链接 这个作业的要求在哪里 作业链接地址 团队名称 代码敲不队 作业学习目标 掌握软件编码实现的工程要求. 第一天 日期:2019/6/15 团队项目 ...
- 00065字符串缓冲区_StringBuilder类
1.StringBuilder类,它也是字符串缓冲区,StringBuilder与它和StringBuffer的有什么不同呢? 它一个可变的字符序列.此类提供一个与 StringBuffer 兼容的 ...
- 参数化取值策略Random
1.Random+Each iteration,跟顺序读取的结果唯一不同的就是这里是随机读取,取值是每次迭代取值 2.Random+Each occurrence,随机取值更新方式 3.R ...