河城荷取 二分答案 最大流
来源:互联网 发布:李谷一 知乎 编辑:程序博客网 时间:2024/05/22 14:48
NKOJ2507 河城荷取
问题描述
在幻想乡,河城荷取是擅长高科技工业的河童。荷取的得意之作除了光学迷彩外,还有震动整个幻想乡的巨型人形『非想天则』。不过由于人形太过巨大,所以为它充能是一件很麻烦的事。人形一共有N个电能池,编号1..N。其中前L个电能池(即编号为1..L的电能池)连接着外部充能接口,而编号为N的电能池连接着动力炉核心。在N个蓄能池之间有M条单向管道,每条管道有一个激活代价cost和电能传输极限limit。当激活度达到某个值时,所以激活代价小于等于这个值的管道都会被激活,但是每一条管道只能够最多传送limit个单位的电能。外部接口到电能池和电能池到动力炉核心的管道传输没有限制并且激活代价为0。现在荷取想往动力炉核心输入至少K个单位的电能,求需要的最小激活度。
输入格式
第1行:4个正整数N,M,L, K
第2..M+1行:4个整数,u,v,limit,cost,表示一条由u到v的管道,传输极限limit,激活代价为cost
输出格式
第1行:1个整数,表示最小激活代价
样例输入
6 5 3 3
1 4 2 4
2 4 3 5
3 5 4 2
4 6 2 3
5 6 3 4
样例输出
4
数据规模
对于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
保证任意(u,v)都只出现一次
显然,对给定的一些边集,输入的最大电流就是最大流。满足输入最大电流不低于K的激活代价显然满足二分性质。所以就可以二分答案,SAP求解。
这里有一个简单的优化:如果直接枚举cost,那么上界最大是1,000,000。但是稍微考虑下可以发现,最终答案一定是某一条边的cost值,所以我们只需要将cost排序后,对于这个数组二分答案即可,上界变小为了80,000。
代码:
#include<stdio.h>#include<cstring>#include<algorithm>#define MAXN 2005#define MAXM 200005#define Min(x,y) ((x<y)?(x):(y))using namespace std;int N,M,L,K,Hash[MAXM];struct node{ int u,v,l,c;}edge[MAXM];int tot,en[MAXM],nex[MAXM],las[MAXN],G[MAXM];void ADD(int x,int y,int l){ en[++tot]=y; nex[tot]=las[x]; las[x]=tot; G[tot]=l;}int S,T,P;int Cnt[MAXN],dis[MAXN];int SAP(int x,int flow){ int i,y,d=0,tmp; if(x==T)return flow; for(i=las[x];i;i=nex[i]) { y=en[i]; if(G[i]&&dis[x]==dis[y]+1) { tmp=SAP(y,Min((flow-d),G[i])); G[i]-=tmp; G[i^1]+=tmp; d+=tmp; if(d==flow||dis[S]>=P)return d; } } Cnt[dis[x]]--; if(Cnt[dis[x]]==0)dis[S]=P; Cnt[++dis[x]]++; return d;}bool check(int In){ memset(las,0,sizeof(las));tot=1; memset(Cnt,0,sizeof(Cnt)); memset(dis,0,sizeof(dis)); P=N+1;S=0;T=N; int i,Ans=0; for(i=1;i<=M;i++)if(edge[i].c<=In)ADD(edge[i].u,edge[i].v,edge[i].l),ADD(edge[i].v,edge[i].u,0); for(i=1;i<=L;i++)ADD(0,i,1e9),ADD(i,0,0); while(dis[S]<=P)Ans+=SAP(S,1e9); return Ans>=K;}int main(){ int i,u,v,l,c,Lans,Rans,mid,x; scanf("%d%d%d%d",&N,&M,&L,&K); for(i=1;i<=M;i++) { scanf("%d%d%d%d",&edge[i].u,&edge[i].v,&edge[i].l,&edge[i].c); Hash[i]=edge[i].c; } sort(Hash+1,Hash+M+1); Hash[M+1]=1e9; Lans=0;Rans=M; while(Lans<=Rans) { mid=Lans+Rans>>1; if(check(Hash[mid]))Rans=mid-1; else Lans=mid+1; } printf("%d",Hash[Lans]);}
- 河城荷取 二分答案 最大流
- HUST1024二分答案+最大流
- pku2112 最大流,弗洛伊德,二分答案
- pku2391 最大流,二分答案,弗洛伊德
- poj 2112 二分答案+最大流
- poj 2112 最大流+floyd+二分答案
- POJ3057 Evacuation 最大流+二分答案
- floyd +二分答案+最大流 poj2112
- bzoj 1532 二分答案+最大流判断
- zzuli1672--二分答案+最大匹配
- [dp][二分答案]最大正方形
- SPOJ 287 网络流最大流+二分答案 解题报告
- POJ 2455 Secret Milking Machine(二分答案+最大流)
- POJ2455 Secret Milking Machine 典型二分答案+最大流判定
- hrbust 1798 秘密产奶机器 (最大流+二分答案)
- POJ 2391 多源多汇拆点最大流 +flody+二分答案
- POJ3228 并查集或二分最大流枚举答案
- BZOJ 1305 CQOI2009 dance跳舞 二分答案+最大流
- 单源最短路径算法(Dijkstra算法)
- 蒟蒻复习之-----Tarjan
- 在Linux下安装MySQL
- 文章获取与单词统计排序
- [bzoj4552][Tjoi2016&Heoi2016]排序 二分+线段树
- 河城荷取 二分答案 最大流
- 51Nod 1035 最长的循环节
- [java]创建新数组的三种方式
- 字符串的连接
- HBase之——Shell基础操作
- LeetCode 328. Odd Even Linked List
- 设置坐标轴长度和范围
- python的MySQL操作增删改查
- VS2017开发Windows服务