BZOJ-1834 网络扩容 最小费用最大流+最大流+乱搞
1834: [ZJOI2010]network 网络扩容
Time Limit: 3 Sec Memory Limit: 64 MB
Submit: 2269 Solved: 1136
[Submit][Status][Discuss]
Description
给定一张有向图,每条边都有一个容量C和一个扩容费用W。这里扩容费用是指将容量扩大1所需的费用。求: 1、 在不扩容的情况下,1到N的最大流; 2、 将1到N的最大流增加K所需的最小扩容费用。
Input
输入文件的第一行包含三个整数N,M,K,表示有向图的点数、边数以及所需要增加的流量。 接下来的M行每行包含四个整数u,v,C,W,表示一条从u到v,容量为C,扩容费用为W的边。
Output
输出文件一行包含两个整数,分别表示问题1和问题2的答案。
Sample Input
5 8 2
1 2 5 8
2 5 9 9
5 1 6 2
5 1 1 8
1 2 8 7
2 5 4 9
1 2 1 1
1 4 2 1
Sample Output
13 19
30%的数据中,N<=100
100%的数据中,N<=1000,M<=5000,K<=10
HINT
Source
Day1
这道题啊,似乎不是很复杂,起码省去了bt建图,充其量是个模板堆上,随便乱搞几行,直接正解。(ZJOI中最水的了吧??)
先按照读入连边。(第一问最大流时不需要费用,可以先存下来,为第二问准备)
Dinic模板一套,第一问A
在第一问的参与网络上,建边。
每两个点相连,边权为inf,费用为之前存下来的。
最后再建一个源,连向1,容量为k,费用为0
zkw模板一套,第二问A
。。。。。
code:(写的冗余QwQ)
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
#define inf 0x7fffffff
struct data{
int from,to,next,c,v,co;
}edge[100010];
int q[100010],h,t;
int dis[100010];
int head[100010]={0},cnt=1;
bool visit[100010],mark[100010];
int n,m,k;
int S,T;
int ans;
int read()
{
int x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
return x*f;
}
void add(int u,int v,int cap,int cost)
{
cnt++;edge[cnt].from=u;edge[cnt].to=v;
edge[cnt].v=cap;edge[cnt].co=cost;
edge[cnt].next=head[u];head[u]=cnt;
}
void insert(int u,int v,int cap,int cost)
{
add(u,v,cap,cost);add(v,u,0,-cost);
}
void add_edge(int u,int v,int cap,int cost)
{
cnt++;edge[cnt].from=u;edge[cnt].to=v;
edge[cnt].v=cap;edge[cnt].c=cost;
edge[cnt].next=head[u];head[u]=cnt;
}
void insert_edge(int u,int v,int cap,int cost)
{
add_edge(u,v,cap,cost);add_edge(v,u,0,-cost);
}
void init()
{
n=read();m=read();k=read();
for (int i=1; i<=m; i++)
{
int u,v,c,w;
u=read();v=read();c=read();w=read();
insert(u,v,c,w);
}
S=1;T=n;
}
bool bfs()
{
memset(dis,-1,sizeof(dis));
q[1]=S;dis[S]=1;h=0;t=1;
while (h<t)
{
int j=q[++h],i=head[j];
while (i)
{
if (dis[edge[i].to]<0 && edge[i].v>0)
{
dis[edge[i].to]=dis[j]+1;
q[++t]=edge[i].to;
}
i=edge[i].next;
}
}
if (dis[T]>0) return true;
else return false;
}
int dfs(int loc,int low)
{
if (loc==T) return low;
int w,used=0;
for (int i=head[loc]; i; i=edge[i].next)
{
if (edge[i].v>0 && dis[edge[i].to]==dis[loc]+1)
{
w=dfs(edge[i].to,min(low-used,edge[i].v));
edge[i].v-=w;edge[i^1].v+=w;
used+=w;if (used==low) return low;
}
}
if (!used) dis[loc]=-1;
return used;
}
int dinic()
{
int tmp=0;
while (bfs())
{
tmp+=dfs(S,inf);
}
return tmp;
}
void problem_1()
{
int tmp=dinic();
printf("%d ",tmp);
}
void make()
{
int num=cnt;
for (int i=2; i<=num; i+=2)
insert_edge(edge[i].from,edge[i].to,inf,edge[i].co);
insert(0,1,k,0);
S=0;
}
bool spfa()
{
memset(visit,0,sizeof(visit));
for (int i=S; i<=T; i++) dis[i]=inf;
h=0,t=1;
q[0]=T;visit[T]=1;dis[T]=0;
while (h<t)
{
int now=q[h];h++;visit[now]=0;
for (int i=head[now]; i; i=edge[i].next)
if (edge[i^1].v && dis[now]-edge[i].c<dis[edge[i].to])
{
dis[edge[i].to]=dis[now]-edge[i].c;
if (!visit[edge[i].to])
{
visit[edge[i].to]=1;
q[t++]=edge[i].to;
}
}
}
return dis[S]!=inf;
}
int dfs1(int loc,int low)
{
mark[loc]=1;
if (loc==T) return low;
int w,used=0;
for (int i=head[loc]; i; i=edge[i].next)
if (dis[edge[i].to]==dis[loc]-edge[i].c && edge[i].v && !mark[edge[i].to])
{
w=dfs1(edge[i].to,min(low-used,edge[i].v));
ans+=w*edge[i].c;
edge[i].v-=w;edge[i^1].v+=w;
used+=w;if (used==low) return low;
}
return used;
}
void zkw()
{
int tmp=0;
while (spfa())
{
mark[T]=1;
while (mark[T])
{
memset(mark,0,sizeof(mark));
tmp+=dfs1(S,inf);
}
}
}
void problem_2()
{
make();
zkw();
printf("%d",ans);
}
int main()
{
init();
problem_1();
problem_2();
return 0;
}
BZOJ-1834 网络扩容 最小费用最大流+最大流+乱搞的更多相关文章
- BZOJ 1834 网络扩容(最大流+费用流)
对于第一问,直接求最大流. 对于第二问,建源点s和汇点t,s连1容量为INF,费用为0的边,n连t容量为最大流+k,费用为0的边.这样就把最大流限制为最多增加k了. 限制需要求扩充的最小费用,原图的边 ...
- BZOJ 1834 网络扩容 最大流+最小费用流
题目链接: https://www.lydsy.com/JudgeOnline/problem.php?id=1834 题目大意: 给定一张有向图,每条边都有一个容量C和一个扩容费用W.这里扩容费用是 ...
- BZOJ1834[ZJOI2010]网络扩容——最小费用最大流+最大流
题目描述 给定一张有向图,每条边都有一个容量C和一个扩容费用W.这里扩容费用是指将容量扩大1所需的费用. 求: 1.在不扩容的情况下,1到N的最大流: 2.将1到N的最大流增加K所需的最小扩容费用 ...
- BZOJ 1834 Luogu P2604 [ZJOI2010]网络扩容 (最小费用最大流)
题目连接: (luogu) https://www.luogu.org/problemnew/show/P2604 (bzoj) https://www.lydsy.com/JudgeOnline/p ...
- BZOJ 1834网络扩容题解
一道不算太难的题目 但是真的很恶心 显然,对于第一问,我们直接无脑打模板就好了 第二问也不是很难,我们将每条边再连一条容量为inf,费用为w的边 但是流量只要小于第一问的答案加k就行了 所以我们增加一 ...
- BZOJ_1834_[ZJOI2010]network 网络扩容_费用流
BZOJ_1834_[ZJOI2010]network 网络扩容_费用流 题意: 给定一张有向图,每条边都有一个容量C和一个扩容费用W.这里扩容费用是指将容量扩大1所需的费用. 求: 1.在不扩容的 ...
- 1834. [ZJOI2010]网络扩容【费用流】
Description 给定一张有向图,每条边都有一个容量C和一个扩容费用W.这里扩容费用是指将容量扩大1所需的费用. 求: 1.在不扩容的情况下,1到N的最大流: 2.将1到N的最大流增加K所需 ...
- hdu 4411 2012杭州赛区网络赛 最小费用最大流 ***
题意: 有 n+1 个城市编号 0..n,有 m 条无向边,在 0 城市有个警察总部,最多可以派出 k 个逮捕队伍,在1..n 每个城市有一个犯罪团伙, 每个逮捕队伍在每个城市可以选 ...
- BZOJ 1927 星际竞速(最小费用最大流)
题目链接:http://61.187.179.132/JudgeOnline/problem.php?id=1927 题意:一个图,n个点.对于给出的每条边 u,v,w,表示u和v中编号小的那个到编号 ...
随机推荐
- AC日记——手写堆ac合并果子(傻子)
今天整理最近的考试题 发现一个东西叫做优先队列 priority_queue(说白了就是大根堆) 但是 我对堆的了解还是很少的 所以 我决定手写一个堆 于是我写了一个简单的堆 手写的堆说白了就是个二叉 ...
- [cb]Unity 项目架构
一.技能机制 二.游戏工程 三.客户端架构
- AutoIT删除Internet临时文件
搜集了几个超赞的方法: 1.删除临时文件 Temporary Internet Files:RunDll32.exe InetCpl.cpl,ClearMyTracksByProcess 8 2. 删 ...
- JMeter学习(二)录制脚本
---------------------------------------------------------------------------------------------------- ...
- eclipse android 不会自动生成R.java文件和包的解决办法
eclipse下编写android程序突然不会自动生成R.java文件和包的解决办法 我的eclipse原来是好好的,什么问题都没有的,结果今天一打开新建一个android程序,发现工程里不会自动 ...
- Beaufort密码
博福特密码,是一种类似于维吉尼亚密码的替代密码,由弗朗西斯·蒲福(Francis Beaufort)发明.它最知名的应用是M-209密码机.博福特密码属于对等加密,即加密演算法与解密演算法相同 博福特 ...
- js判断浏览器种类以及版本号(从jquery1.8中抠出来的)
var myLibs = { // Use of jQuery.browser is frowned upon. // More details: http://api.jquery.com/jQue ...
- iOS数据本地持久化
p1:归档.Preference(NSUserDefault).沙盒存储 iOS开发中本地存储主要有三种形式 XML属性列表(plist)归档 Preference(偏好设置) NSKeyedAr ...
- ie6,ie7兼容性总结(转)
其实浏览器的不兼容,我们往往是各个浏览器对于一些标准的定义不一致导致的,因此,我们可以进行一些初始化,很多问题都很轻松解决. 下面是14条特殊情况仅供参考: 1. 文字本身的大小不兼容.同样是font ...
- C语言中的深拷贝和浅拷贝
//C语言中的深拷贝和浅拷贝 #define _CRT_SECURE_NO_WARNINGS #include<stdio.h> #include<stdlib.h> #inc ...