【codevs1422】河城荷取 二分+dinic
2015-11-24 16:37
288 查看
题目描述 Description
在幻想乡,河城荷取是擅长高科技工业的河童。荷取的得意之作除了光学迷彩外,还有震动整个幻想乡的巨型人形『非想天则』。不过由于人形太过巨大,所以为它充能是一件很麻烦的事。人形一共有N个电能池,编号1..N。其中前L个电能池(即编号为1..L的电能池)连接着外部充能接口,而编号为N的电能池连接着动力炉核心。在N个蓄能池之间有M条单向管道,每条管道有一个激活代价cost和电能传输极限limit。当激活度达到某个值时,所以激活代价小于等于这个值的管道都会被激活,但是每一条管道只能够最多传送limit个单位的电能。外部接口到电能池和电能池到动力炉核心的管道传输没有限制并且激活代价为0。现在荷取想往动力炉核心输入至少K个单位的电能,求需要的最小激活度。输入描述 Input Description
第1行:4个正整数N,M,L, K第2..M行:4个整数,u,v,limit,cost,表示一条由u到v的管道,传输极限limit,激活代价为cost
输出描述 Output Description
第1行:1个整数,表示最小激活代价样例输入 Sample Input
[code]6 5 3 3 1 4 2 4 2 4 3 5 3 5 4 2 4 6 2 3 5 6 3 4
样例输出 Sample Output
[code]4
数据范围及提示 Data Size & Hint
数据范围对于30%的数据:1 ≤ L ≤ N ≤ 100,0 ≤ M ≤ 2,000,1 ≤ cost ≤ 10,000
对于60%的数据:1 ≤ L ≤ N ≤ 1,000,0 ≤ M ≤ 20,000,1 ≤ cost ≤ 10,000
对于100%的数据:1 ≤ L ≤ N ≤ 2,000,0 ≤ M ≤ 80,000,1 ≤ cost ≤ 1,000,000
对于100%的数据:1 ≤ limit ≤ 1,000
提示
样例解释:
当激活度为4时,除了(2,4)外其他管道都能够使用。此时能够输入恰好4个单位电能。具体如下:
(1,4) 输送2个单位电力
(4,6) 输送2个单位电力
(3,5) 输送2个单位电力
(5,6) 输送2个单位电力
注意:
保证任意(u,v)都只出现一次。
第一次做这个题,dinic写傻了
然后过了两天再来写,一遍A了…………
总之就是不要忘记清空数组!!!别的都好说
代码:
[code]#include<cstdio> #include<iostream> #include<cstring> #include<algorithm> #include<queue> using namespace std; const int SZ=1000010; const int INF=1000000000; int head[SZ],nxt[SZ],tot=1,s,e; struct edge{ int t,d; }l[SZ]; void build(int f,int t,int d) { l[++tot].t=t; l[tot].d=d; nxt[tot]=head[f]; head[f]=tot; } int deep[SZ]; queue<int> q; bool bfs(int s) { q.push(s); deep[s]=1; while(q.size()) { int f=q.front(); q.pop(); for(int i=head[f];i;i=nxt[i]) { int v=l[i].t; if(l[i].d && !deep[v]) { deep[v]=deep[f]+1; q.push(v); } } } if(deep[e]) return true; return false; } int dfs(int u,int flow) { if(u==e || flow==0) return flow; int ans=0; for(int i=head[u];i;i=nxt[i]) { int v=l[i].t; if(l[i].d && deep[v]==deep[u]+1) { int f=dfs(v,min(flow,l[i].d)); if(f > 0) { l[i].d-=f; l[i^1].d+=f; flow-=f; ans+=f; if(flow==0) return ans; } } } if(ans == 0) deep[u]=INF; return ans; } int dinic() { int ans=0; while(bfs(s)) { int tmp=dfs(s,INF); if(tmp==0) break; ans+=tmp; memset(deep,0,sizeof(deep)); } return ans; } int ff[SZ],tt[SZ],ll[SZ],dd[SZ]; int n,m,L,k; void init() { memset(head,0,sizeof(head)); memset(nxt,0,sizeof(nxt)); memset(l,0,sizeof(l)); memset(deep,0,sizeof(deep)); tot=1; } void build_graph(int ans) { init(); for(int i=1;i<=m;i++) { if(dd[i]<=ans) { build(ff[i],tt[i],ll[i]); build(tt[i],ff[i],0); } } for(int i=1;i<=L;i++) { build(s,i,INF); build(i,s,0); } } int div() { int s=-1,t=1000000; while(t-s>1) { int mid=(t+s)>>1; build_graph(mid); if(dinic()>=k) t=mid; else s=mid; } return t; } int main() { scanf("%d%d%d%d",&n,&m,&L,&k); for(int i=1;i<=m;i++) { scanf("%d%d%d%d",&ff[i],&tt[i],&ll[i],&dd[i]); } s=n+1,e=n; printf("%d",div()); return 0; }
相关文章推荐
- 在 Windows 上安装Rabbit MQ 指南
- IOS用CGContextRef画各种图形(文字、圆、直线、弧线、矩形、扇形、椭圆、三角形、圆角矩形、贝塞尔曲线、图片)
- ADT下载地址整理
- Android MVP模式
- 《JAVA与模式》之合成模式
- Quartz Spring与Spring Task总结
- C++指针详解
- C#获取当前路径的7种方法
- 南大软院大神养成计划--day09
- 对于复杂交互的前端页面架构的思考(干货)
- 最新支付宝集成遇到的一些坑。
- 粘性定位position:sticky用法,手机移动设备:flex布局
- Android uncovers master-key 漏洞分析
- android开发之线程基础
- kali攻防第2章 内网称霸之渗透安卓系统
- Win10手记-为应用集成SQLite(一)
- linux下的硬链接和软链接
- Android讯飞语音云语音听写学习
- 一张图告诉你,只会HTML还不够!
- memcpy函数