题意:给你一张图,每个城市有一些人,有不超过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 二分 网络流的更多相关文章

  1. hihoCoder 1389 Sewage Treatment 【二分+网络流+优化】 (ACM-ICPC国际大学生程序设计竞赛北京赛区(2016)网络赛)

    #1389 : Sewage Treatment 时间限制:2000ms 单点时限:2000ms 内存限制:256MB 描述 After years of suffering, people coul ...

  2. POJ 2455 Secret Milking Machine(搜索-二分,网络流-最大流)

    Secret Milking Machine Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 9658   Accepted: ...

  3. BZOJ_3993_[SDOI2015]星际战争_二分+网络流

    BZOJ_3993_[SDOI2015]星际战争_二分+网络流 Description 3333年,在银河系的某星球上,X军团和Y军团正在激烈地作战.在战斗的某一阶段,Y军团一共派遣了N个巨型机器人进 ...

  4. 【bzoj3130】[Sdoi2013]费用流 二分+网络流最大流

    题目描述 Alice和Bob做游戏,给出一张有向图表示运输网络,Alice先给Bob一种最大流方案,然后Bob在所有边上分配总和等于P的非负费用.Alice希望总费用尽量小,而Bob希望总费用尽量大. ...

  5. 【bzoj1822】[JSOI2010]Frozen Nova 冷冻波 计算几何+二分+网络流最大流

    题目描述 WJJ喜欢“魔兽争霸”这个游戏.在游戏中,巫妖是一种强大的英雄,它的技能Frozen Nova每次可以杀死一个小精灵.我们认为,巫妖和小精灵都可以看成是平面上的点. 当巫妖和小精灵之间的直线 ...

  6. 【bzoj1733】[Usaco2005 feb]Secret Milking Machine 神秘的挤奶机 二分+网络流最大流

    题目描述 Farmer John is constructing a new milking machine and wishes to keep it secret as long as possi ...

  7. 【bzoj1532】[POI2005]Kos-Dicing 二分+网络流最大流

    题目描述 Dicing 是一个两人玩的游戏,这个游戏在Byteotia非常流行. 甚至人们专门成立了这个游戏的一个俱乐部. 俱乐部的人时常在一起玩这个游戏然后评选出玩得最好的人.现在有一个非常不走运的 ...

  8. BZOJ_1532_[POI2005]Kos-Dicing_二分+网络流

    BZOJ_1532_[POI2005]Kos-Dicing_二分+网络流 Description Dicing 是一个两人玩的游戏,这个游戏在Byteotia非常流行. 甚至人们专门成立了这个游戏的一 ...

  9. HDU 3081 Marriage Match II 二分 + 网络流

    Marriage Match II 题意:有n个男生,n个女生,现在有 f 条男生女生是朋友的关系, 现在有 m 条女生女生是朋友的关系, 朋友的朋友是朋友,现在进行 k 轮游戏,每轮游戏都要男生和女 ...

随机推荐

  1. 【LeetCode】Array

    [11] Container With Most Water [Medium] O(n^2)的暴力解法直接TLE. 正确的解法是Two Pointers. O(n)的复杂度.保持两个指针i,j:分别指 ...

  2. jquery 实现复选框选择效果

    html <!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <ti ...

  3. eclipse中服务器找不到项目怎么解决

    在我们运行项目前,都需要将项目部署到tomcat上,但是有时我们会遇到这种情况:项目明明存在,但是eclipse中tomcat的add and remove找不到项目,无法部署,那么这个问题该如何解决 ...

  4. zookeeper问题排查

    一.无法启动 zookeeper之前可以很好的运行,由于zk集群不是正常的关闭,比如 强制Linux关闭,直接执行kill 命令zk的进程等原因导致zookeeper启动不了 启动命令后,查看状态,会 ...

  5. Halo(一)

    @EnableJpaAuditing 审计功能(启动类配置) 在实际的业务系统中,往往需要记录表数据的创建时间.创建人.修改时间.修改人. 每次手动记录这些信息比较繁琐,SpringDataJpa 的 ...

  6. SLA(服务等级协议)

    SLA:Service-Level Agreement的缩写,意思是服务等级协议.是关于网络服务供应商和客户间的一份合同,其中定义了服务类型.服务质量和客户付款等术语. 定义SLA:Service-L ...

  7. Linux系统之-文件系统,桌面环境

    文件系统 文件类型普通文件,目录文件,连接文件,设备与设备文件,套接字,管道 普通文件(regular file):就是一般存取的文件,由ls -al显示出来的属性中,第一个属性为 [-],例如 [- ...

  8. Python字典操作及课后练习

    '''dict,唯一一个映射数据类型数据类型划分:可变数据类型,不可变数据类型不可变数据类型:元组,bool int str(对str的任何改变都是形成了新的str,对原来的str没有改变)可变数据类 ...

  9. 三种做法:BZOJ 2780: [Spoj]8093 Sevenk Love Oimaster

    目录 题意 思路 AC_Code1 AC_Code2 AC_Code3 参考 @(bzoj 2780: [Spoj]8093 Sevenk Love Oimaster) 题意 链接:here 有\(n ...

  10. leetcode上的一些栈、队列问题

    20-有效的括号 思路:主要考察栈的一些基本操作,像push()(将数据压入栈顶).top()(取栈顶的数据但不删除).pop()(直接删除栈顶的元素).empty()(判断栈是否为空).这题就是先把 ...