Gym 102007I 二分 网络流
题意:给你一张图,每个城市有一些人,有不超过10个城市有避难所,避难所有容量上限,问最快多久可以让所有人进入避难所?
思路:二分时间,对于每个时间跑一遍最大流,判断最大流是不是人数即可。我们还需要用二进制优化一下,对于每个二分的时间,我们需要预处理出某个城市可以到达哪些避难所,表示成状态。如果在当前时间下两个城市可以到达的避难所是一样的,我们就可以用一个状态表示,这样把点数限制在了1e3级别。
代码:
#include <bits/stdc++.h>
#include <ext/pb_ds/priority_queue.hpp>
#define LL long long
#define pLi pair<LL ,int>
#define pii pair<int, int>
#define INF 0x3f3f3f3f3f3f3f3f
using namespace std;
using namespace __gnu_pbds;
const int maxn = 200100;
const int maxm = 501000;
typedef __gnu_pbds::priority_queue<pLi, greater<pLi>, pairing_heap_tag> Heap;
int heade[maxn],
Nexte[maxm], vere[maxm], edgee[maxm], tote;
LL dis[10][maxn];
pair<int, int> b[20];
int n, k;
int a[maxn];
LL re[maxn * 10];
void adde(int x, int y, int z) {
vere[++tote] = y;
edgee[tote] = z;
Nexte[tote] = heade[x];
heade[x] = tote;
}
Heap q;
int s, t;
void dijkstra(int s, int flag) {
memset(dis[flag], 0x3f, sizeof(dis[flag]));
Heap::point_iterator id[maxn];
dis[flag][s] = 0;
id[s] = q.push(make_pair(dis[flag][s], s));
while(!q.empty()) {
int x = q.top().second;
q.pop();
for (int i = heade[x]; i; i = Nexte[i]) {
int y = vere[i], z = edgee[i];
if(dis[flag][y] > dis[flag][x] + z) {
dis[flag][y] = dis[flag][x] + z;
if(id[y] != 0) q.modify(id[y], make_pair(dis[flag][y], y));
else id[y] = q.push(make_pair(dis[flag][y], y));
}
}
}
}
int head[maxn], Next[maxn * 25], ver[maxn * 25], tot;
LL edge[maxn * 25];
int deep[maxn];
void add(int x, int y, LL z) {
ver[++tot] = y, edge[tot] = z, Next[tot] = head[x], head[x] = tot;
ver[++tot] = x, edge[tot] = 0, Next[tot] = head[y], head[y] = tot;
}
queue<int> Q;
bool bfs(LL limit) {
memset(deep, 0, sizeof(deep));
while(Q.size())Q.pop();
Q.push(s); deep[s] = 1;
while(Q.size()) {
int x = Q.front();Q.pop();
for (int i = head[x]; i; i = Next[i]) {
if(edge[i] && !deep[ver[i]]) {
Q.push(ver[i]);
deep[ver[i]] = deep[x] + 1;
if(ver[i] == t) return 1;
}
}
}
return 0;
}
LL dinic(int x, LL flow) {
if(x == t) return flow;
LL rest = flow, k;
for (int i = head[x]; i && rest; i = Next[i]) {
if(edge[i] && deep[ver[i]] == deep[x] + 1) {
k = dinic(ver[i], min(rest, edge[i]));
if(!k) deep[ver[i]] = 0;
edge[i] -= k;
edge[i ^ 1] += k;
rest -= k;
}
}
return flow - rest;
}
LL solve(int now) {
tot = 1;
LL maxflow = 0;
// memset(head, 0, sizeof(head));
memset(head, 0, sizeof(int) * (n + 1));
for (int i = 0; i < k; i++)
head[b[i].first + n] = 0;
head[t] = 0;
for (int i = 1; i <= n; i++) {
if(a[i])
add(s, i, a[i]);
}
LL tmp;
for (int i = 1; i <= n; i++) {
tmp = 0;
if(a[i] == 0) continue;
for (int j = 0; j < k; j++) {
if(dis[j][i] >= re[now]) continue;
tmp += b[j].second;
add(i, b[j].first + n, INF);
}
if(tmp < a[i]) {
return 0;
}
}
for (int i = 0; i < k; i++)
add(b[i].first + n, t, b[i].second);
LL flow;
while(bfs(re[now])) {
while(flow = dinic(s, INF)) maxflow += flow;
}
return maxflow;
}
int main() {
LL cnt = 0;
s = 0, t = 2 * n + 20;
int m, x, y, z;
scanf("%d%d%d", &n, &m, &k);
for (int i = 1; i <= n; i++) {
scanf("%d", &a[i]);
cnt += a[i];
}
for (int i = 1; i <= m; i++) {
scanf("%d%d%d", &x, &y, &z);
adde(x, y, z);
adde(y, x, z);
}
for (int i = 0; i < k; i++) {
scanf("%d%d", &b[i].first, &b[i].second);
dijkstra(b[i].first, i);
}
for (int i = 0; i < k; i++)
for (int j = 1; j <= n; j++) {
re[++tot] = dis[i][j];
}
sort(re + 1, re + 1 + tot);
int sz = unique(re + 1, re + 1 + tot) - (re + 1);
int l = 1, r = sz + 1;
re[sz + 1] = INF;
while(l < r) {
int mid = (l + r) >> 1;
if(solve(mid) == cnt) r = mid;
else l = mid + 1;
}
printf("%lld\n", re[l - 1]);
}
Gym 102007I 二分 网络流的更多相关文章
- hihoCoder 1389 Sewage Treatment 【二分+网络流+优化】 (ACM-ICPC国际大学生程序设计竞赛北京赛区(2016)网络赛)
#1389 : Sewage Treatment 时间限制:2000ms 单点时限:2000ms 内存限制:256MB 描述 After years of suffering, people coul ...
- POJ 2455 Secret Milking Machine(搜索-二分,网络流-最大流)
Secret Milking Machine Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 9658 Accepted: ...
- BZOJ_3993_[SDOI2015]星际战争_二分+网络流
BZOJ_3993_[SDOI2015]星际战争_二分+网络流 Description 3333年,在银河系的某星球上,X军团和Y军团正在激烈地作战.在战斗的某一阶段,Y军团一共派遣了N个巨型机器人进 ...
- 【bzoj3130】[Sdoi2013]费用流 二分+网络流最大流
题目描述 Alice和Bob做游戏,给出一张有向图表示运输网络,Alice先给Bob一种最大流方案,然后Bob在所有边上分配总和等于P的非负费用.Alice希望总费用尽量小,而Bob希望总费用尽量大. ...
- 【bzoj1822】[JSOI2010]Frozen Nova 冷冻波 计算几何+二分+网络流最大流
题目描述 WJJ喜欢“魔兽争霸”这个游戏.在游戏中,巫妖是一种强大的英雄,它的技能Frozen Nova每次可以杀死一个小精灵.我们认为,巫妖和小精灵都可以看成是平面上的点. 当巫妖和小精灵之间的直线 ...
- 【bzoj1733】[Usaco2005 feb]Secret Milking Machine 神秘的挤奶机 二分+网络流最大流
题目描述 Farmer John is constructing a new milking machine and wishes to keep it secret as long as possi ...
- 【bzoj1532】[POI2005]Kos-Dicing 二分+网络流最大流
题目描述 Dicing 是一个两人玩的游戏,这个游戏在Byteotia非常流行. 甚至人们专门成立了这个游戏的一个俱乐部. 俱乐部的人时常在一起玩这个游戏然后评选出玩得最好的人.现在有一个非常不走运的 ...
- BZOJ_1532_[POI2005]Kos-Dicing_二分+网络流
BZOJ_1532_[POI2005]Kos-Dicing_二分+网络流 Description Dicing 是一个两人玩的游戏,这个游戏在Byteotia非常流行. 甚至人们专门成立了这个游戏的一 ...
- HDU 3081 Marriage Match II 二分 + 网络流
Marriage Match II 题意:有n个男生,n个女生,现在有 f 条男生女生是朋友的关系, 现在有 m 条女生女生是朋友的关系, 朋友的朋友是朋友,现在进行 k 轮游戏,每轮游戏都要男生和女 ...
随机推荐
- python时间日期处理
一.模块介绍: 1.time模块接近操作系统,模块中的大多数函数是调用了所在平台C library的同名函数,部分函数式平台相关的:基于Unix Timestamp,能表述的日期范围被限定在 1970 ...
- exp ORA-01455: converting column overflows integer datatype
EXP-00008: ORACLE error 1455 encounteredORA-01455: converting column overflows integer datatype add ...
- 西电源ubuntu12
deb http://linux.xidian.edu.cn/mirrors/ubuntu/ precise main restricted universe multiverse #deb-src ...
- Linux eth0, eth1, ..., eth%d 的生成【转】
转自:https://blog.csdn.net/xiruanliuwei/article/details/78765255 一直很好奇,Linux下的eth0, eth1,eth2等是如何生成的~ ...
- JSP自定义方法标签
1.自定义方法标签 引入方式示例: <%@ taglib prefix="fns" uri="/WEB-INF/tlds/fns.tld" %> 写 ...
- JRE和JVM的区别
JRE和JVM的区别 JRE(JavaRuntimeEnvironment,Java运行环境),也就是Java平台.所有的Java程序都要在JRE下才能运行.JDK的工具也是Java程序, ...
- appium-Android的驱动程序
Appium Android Driver是Android设备的测试自动化工具.Appium Android驱动程序自动化原生的,混合的和移动的Web应用程序,在模拟器,仿真器和真实设备上进行测试.A ...
- 四. jenkins部署springboot项目(1)--window环境
前提:jenkins和springboot运行在同一台机器 springboot项目使用git和maven jenkins所需的插件如Maven,Git等这里就不再详述. 1.jenkins配置git ...
- Openstack组件部署 — Overview和前期环境准备
目录 目录 前言 软件环境 Openstack 简介 Openstack 架构 Openstack Install Overview 创建Node虚拟机 环境准备 基础设置 Install OpenS ...
- CentOS安装 netdata 实时监视 Linux 系统性能
作为一个 Linux 系统的管理员,为了随时了解系统资源的占用情况,有必要使用专门的系统监视工具.如果你需要对 Linux 系统.应用程序.SNMP 设备进行实时的性能监视,那么 netdata 这个 ...