洛谷 - P1462 - 通往奥格瑞玛的道路 - 二分 - Dijkstra
https://www.luogu.org/problem/P1462
感觉,要二分最大收费权的城市,把小于等于它的全部插进去,Dijkstra一下求出最小的血量。这样感觉太暴力了。
考虑只有10000个城市,sort一下,每条无向边都由排名靠后的城市插入。按收费顺序插入城市,直到并查集中1和n连通,来一次Dijkstra求出所需的血量。
假如所需血量已经>=b,说明不合法。
这个时候插入下一个城市及其连通的边,考虑会发生什么改变?首先到达这个城市的最短距离必定是从连出城市走对应路径过来的。
其次它可能会对整个图进行一次更新。所以这个复杂度也是惊人。
所以还是二分城市,要log1e5=15,插入对应的边5e4,跑一次Dijkstra要5e4log5e4=8e5,小得很。
想着至少要过一半吧,没想到一发就全AC了。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int MAXN = 1e4 + 5, INF = 0x3f3f3f3f;
struct Edge {
int v, w;
Edge() {}
Edge(int v, int w): v(v), w(w) {}
};
bool vis[MAXN];
int dis[MAXN];
vector<Edge> G[MAXN];
int fa[MAXN];
int find(int x) {
return fa[x] == x ? x : fa[x] = find(fa[x]);
}
void merge(int x, int y) {
int fx = find(x), fy = find(y);
fa[fy] = fx;
}
struct City {
int id, f;
bool operator<(const City &c)const {
return f < c.f;
}
} city[MAXN];
int n, b;
void Init() {
for(int i = 0; i <= n; ++i)
fa[i] = i;
memset(vis, 1, sizeof(vis[0]) * (n + 1));
memset(dis, INF, sizeof(dis[0]) * (n + 1));
}
void AddCity(int Ceil) {
for(int i = 1; i <= Ceil; ++i) {
int u = city[i].id;
vis[u] = 0;
for(auto ei : G[u])
merge(u, ei.v);
}
}
priority_queue<pair<int, int> > pq;
int Dijkstra(int s) {
pq.push({0, 1});
dis[1] = 0;
while(!pq.empty()) {
int u = pq.top().second;
pq.pop();
if(vis[u])
continue;
vis[u] = 1;
for(auto ei : G[u]) {
int v = ei.v, w = ei.w;
if(!vis[v] && dis[u] + w < dis[v]) {
dis[v] = dis[u] + w;
pq.push({-dis[v], v});
}
}
}
return dis[n];
}
bool check(int Ceil) {
Init();
AddCity(Ceil);
if(find(1) != find(n))
return false;
int res = Dijkstra(1);
return res < b;
}
int main() {
#ifdef Yinku
freopen("Yinku.in", "r", stdin);
#endif // Yinku
int m;
scanf("%d%d%d", &n, &m, &b);
for(int i = 1; i <= n; ++i) {
scanf("%d", &city[i].f);
city[i].id = i;
}
sort(city + 1, city + 1 + n);
for(int i = 1; i <= m; ++i) {
int u, v, w;
scanf("%d%d%d", &u, &v, &w);
G[u].emplace_back(Edge(v, w));
G[v].emplace_back(Edge(u, w));
}
int L = 1, R = n, M;
while(1) {
M = L + R >> 1;
if(L == M) {
if(check(L)) {
printf("%d\n", city[L].f);
return 0;
} else if(check(R)) {
printf("%d\n", city[R].f);
return 0;
}
puts("AFK");
return 0;
}
if(check(M))
R = M;
else
L = M + 1;
}
}
洛谷 - P1462 - 通往奥格瑞玛的道路 - 二分 - Dijkstra的更多相关文章
- 洛谷P1462 通往奥格瑞玛的道路[二分答案 spfa 离散化]
题目背景 在艾泽拉斯大陆上有一位名叫歪嘴哦的神奇术士,他是部落的中坚力量 有一天他醒来后发现自己居然到了联盟的主城暴风城 在被众多联盟的士兵攻击后,他决定逃回自己的家乡奥格瑞玛 题目描述 在艾泽拉斯, ...
- 洛谷P1462通往奥格瑞玛的道路——二分答案最短路
题目:https://www.luogu.org/problemnew/show/P1462 最大值最小问题,二分答案. 代码如下: #include<iostream> #include ...
- 洛谷 P1462 通往奥格瑞玛的道路——二分+spfa
上一波链接 https://www.luogu.org/problem/P1462 这道题我们考虑二分答案 然后每次跑一次spfa判断是否能够到达n点 tips:在不考虑负权边的前提下我们写最短路最好 ...
- 洛谷 P1462 通往奥格瑞玛的道路 二分 最短路
#include<cstdio> #include<queue> #include<cstring> #include<algorithm> using ...
- 洛谷P1462 通往奥格瑞玛的道路(二分+spfa,二分+Dijkstra)
洛谷P1462 通往奥格瑞玛的道路 二分费用. 用血量花费建图,用单源最短路判断 \(1\) 到 \(n\) 的最短路花费是否小于 \(b\) .二分时需要不断记录合法的 \(mid\) 值. 这里建 ...
- 洛谷 P1462 通往奥格瑞玛的道路 题解
P1462 通往奥格瑞玛的道路 题目背景 在艾泽拉斯大陆上有一位名叫歪嘴哦的神奇术士,他是部落的中坚力量 有一天他醒来后发现自己居然到了联盟的主城暴风城 在被众多联盟的士兵攻击后,他决定逃回自己的家乡 ...
- 洛谷 P1462 通往奥格瑞玛的道路 解题报告
P1462 通往奥格瑞玛的道路 题目背景 在艾泽拉斯大陆上有一位名叫歪嘴哦的神奇术士,他是部落的中坚力量 有一天他醒来后发现自己居然到了联盟的主城暴风城 在被众多联盟的士兵攻击后,他决定逃回自己的家乡 ...
- 洛谷——P1462 通往奥格瑞玛的道路
P1462 通往奥格瑞玛的道路 题目背景 在艾泽拉斯大陆上有一位名叫歪嘴哦的神奇术士,他是部落的中坚力量 有一天他醒来后发现自己居然到了联盟的主城暴风城 在被众多联盟的士兵攻击后,他决定逃回自己的家乡 ...
- 洛谷 P1462 通往奥格瑞玛的道路
洛谷 题意:要求在限定油耗内,求最小花费的最大值. 求最小值最大很容易想到二分答案.所以我们往二分的方向去想. 我们二分一个费用,然后要保证到终点时满足限定油耗,所以跑最短路. 不过松弛条件要改一下: ...
随机推荐
- [CF11D]A Simple Task 题解
题解 我们从最简单的思路开始考虑,首先看到题目发现\(n\)非常小,于是很容易想到状态压缩. 我们考虑比较直觉的状态,f[i][j][k]表示以i为起点,当前在j,之前去过的点状态为k的简单环的方案数 ...
- PKUWC2020爆零记
抱歉,这么晚才更. 事实是:我都没有去 所以爆零了 QwQ
- 【gym102394B】Binary Numbers(DP)
题意:From https://blog.csdn.net/m0_37809890/article/details/102886956 思路: 可以发现转移就是右上角的一个区间前缀和 std只要开1倍 ...
- 【Leetcode】二进制求和
解题思路: 1. 首先在两个字符串前面补‘0’,使它们等长.否则要一直监督操作是否超出两个字符串的索引. 2. 从后向前遍历所有位数,同位相加.字符相加,利用ASCII码,字符在内部都用数字表示,我们 ...
- Spring Boot教程(十二)整合elk(1)
elk 简介 Elasticsearch是个开源分布式搜索引擎,它的特点有:分布式,零配置,自动发现,索引自动分片,索引副本机制,restful风格接口,多数据源,自动搜索负载等. Logstash是 ...
- bestcoder#9--1001--Lotus and Characters
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 262144/131072 K (Java/Others) 问题描述 Lotus有nn种字母, ...
- select * from (XXXXX)[字符]——写法解析
步骤:1.先执行括号里的语句:查询 select id from three ,将查询出来的数据作为一个结果集 取名为 a2.然后 再 select * from a 查询a ,将 结果集a 全部查询 ...
- PHP mac localhost 环境下发送邮件
转载自:http://mabblog.com/blog/2011/09/lion-smtp-postfix-relay-and-dreamhost/ When developing web-apps ...
- python之正则匹配match:search findall
match:从开头位置匹配,只匹配一次,开头匹配不上,则不继续匹配 a,b,\w+ match(a,"abcdef") 匹配a >>> re.match(&quo ...
- HDU6534 Chika and Friendly Pairs(莫队,树状数组)
HDU6534 Chika and Friendly Pairs 莫队,树状数组的简单题 #include<bits/stdc++.h> using namespace std; cons ...