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最小成本 第一问直接运行的最大流量 第二个问题将是连接到一个流的末端每个边缘的起点是正 ...
随机推荐
- 洛谷P1297 [国家集训队]单选错位_数学期望
考虑第 iii 位, 那么当前共有 a[i]a[i]a[i] 种选项,那么当前选项正确的情况就是下一个被误填的答案与当前答案相同.换句话说,当前答案一共有 a[i]a[i]a[i] 种可能,而下一个答 ...
- 路飞学城Python-Day151
sprapy框架能够在pycharm中调试的方式 需要在配置文件中加上一个文件,文件的内容为 start.py #!/usr/bin/env python # -*- coding:utf-8 -*- ...
- php多维数组的指定单个字段排序
多维数组如何根据指定键值?比如现在有数组结构如下: ,,,,,'subject' => 'math'), 1 => array('name' => '3班','avgScore'=& ...
- Project Euler 48 Self powers( 大数求余 )
题意: 项的自幂级数求和为 11 + 22 + 33 + - + 1010 = 10405071317. 求如下一千项的自幂级数求和的最后10位数字:11 + 22 + 33 + - + 100010 ...
- keepalived实现IP地址高可用
yum -y install keepalived vim /etc/keepalived/keepalived.conf global_defs { router_id LVS_DEVEL_ngin ...
- Zend 官方框架增加 Swoole 协程支持 !
前言 Zend Framework 是 PHP 的官方框架,随着 Zend-Expressive-Swoole 0.2.2 的发布,率先支持了 Swoole 4 的协程功能,现在可以仅通过一个配置即可 ...
- jsp js action之间传值
1.struts2 action如何向JSP的JS函数传值 action中定义变量 public class TestAction extends ActionSupport implements S ...
- 【CodeForces 574B】Bear and Three Musketeers
[链接] 我是链接,点我呀:) [题意] [题解] 枚举每一条边(x,y) 然后再枚举y的出度z 看看g[x][z]是否等于1(表示联通) 如果等于1就说明找到了一个三元环,则尝试用它们的出度和-6更 ...
- 洛谷 U3346 A1-偶回文数
U3346 A1-偶回文数 题目背景 方方方很喜欢回文数,于是zzq就出了一道关于回文数的题目. 因为偶回文数比较简单,所以方方方就把它放在了第一题... 题目描述 我们定义一个长度为偶数的回文数叫做 ...
- HTML5实现歌词同步
开篇 HTML5的最强大之处莫过于对媒体文件的处理,如利用一个简单的vedio标签就能够实现视频播放.相似地,在HTML5中也有相应的处理音频文件的标签,那就是audio标签 在线Demo audio ...