BZOJ-1834 网络扩容 最小费用最大流+最大流+乱搞
2016-01-17 21:18
651 查看
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
先按照读入连边。(第一问最大流时不需要费用,可以先存下来,为第二问准备)
Dinic模板一套,第一问A
在第一问的参与网络上,建边。
每两个点相连,边权为inf,费用为之前存下来的。
最后再建一个源,连向1,容量为k,费用为0
zkw模板一套,第二问A
。。。。。
code:(写的冗余QwQ)
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 网络扩容 最小费用最大流+最大流+乱搞
- 【转】CentOS 7.0系统安装配置图解教程 | 系统运维(除了网络)
- 从网络Url中下载文件到本地
- android网络编程 二(Apache HttpClient)
- android网络编程 一(HttpURLConnection)
- Android中的Http通信(四)之多线程下载数据
- TCP协议中的三次握手和四次挥手
- TCP三次握手的理解
- TCP的流量控制和拥塞控制
- httpclient,socket
- iOS9https设置info.plist
- CentOS网络配置详解
- CentOS网络配置详解
- Fiddler- -Composer创建和发送HTTP Request
- Java高级部分网络编程重点总结
- MFC HTTP访问URL
- (二)计算机网络体系结构与参考模型
- httpd-2.4特性
- Android&nbsp;4.0&nbsp;HttpURLCon…
- NAT,网络地址转换详解