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的更多相关文章

  1. 洛谷P1462 通往奥格瑞玛的道路[二分答案 spfa 离散化]

    题目背景 在艾泽拉斯大陆上有一位名叫歪嘴哦的神奇术士,他是部落的中坚力量 有一天他醒来后发现自己居然到了联盟的主城暴风城 在被众多联盟的士兵攻击后,他决定逃回自己的家乡奥格瑞玛 题目描述 在艾泽拉斯, ...

  2. 洛谷P1462通往奥格瑞玛的道路——二分答案最短路

    题目:https://www.luogu.org/problemnew/show/P1462 最大值最小问题,二分答案. 代码如下: #include<iostream> #include ...

  3. 洛谷 P1462 通往奥格瑞玛的道路——二分+spfa

    上一波链接 https://www.luogu.org/problem/P1462 这道题我们考虑二分答案 然后每次跑一次spfa判断是否能够到达n点 tips:在不考虑负权边的前提下我们写最短路最好 ...

  4. 洛谷 P1462 通往奥格瑞玛的道路 二分 最短路

    #include<cstdio> #include<queue> #include<cstring> #include<algorithm> using ...

  5. 洛谷P1462 通往奥格瑞玛的道路(二分+spfa,二分+Dijkstra)

    洛谷P1462 通往奥格瑞玛的道路 二分费用. 用血量花费建图,用单源最短路判断 \(1\) 到 \(n\) 的最短路花费是否小于 \(b\) .二分时需要不断记录合法的 \(mid\) 值. 这里建 ...

  6. 洛谷 P1462 通往奥格瑞玛的道路 题解

    P1462 通往奥格瑞玛的道路 题目背景 在艾泽拉斯大陆上有一位名叫歪嘴哦的神奇术士,他是部落的中坚力量 有一天他醒来后发现自己居然到了联盟的主城暴风城 在被众多联盟的士兵攻击后,他决定逃回自己的家乡 ...

  7. 洛谷 P1462 通往奥格瑞玛的道路 解题报告

    P1462 通往奥格瑞玛的道路 题目背景 在艾泽拉斯大陆上有一位名叫歪嘴哦的神奇术士,他是部落的中坚力量 有一天他醒来后发现自己居然到了联盟的主城暴风城 在被众多联盟的士兵攻击后,他决定逃回自己的家乡 ...

  8. 洛谷——P1462 通往奥格瑞玛的道路

    P1462 通往奥格瑞玛的道路 题目背景 在艾泽拉斯大陆上有一位名叫歪嘴哦的神奇术士,他是部落的中坚力量 有一天他醒来后发现自己居然到了联盟的主城暴风城 在被众多联盟的士兵攻击后,他决定逃回自己的家乡 ...

  9. 洛谷 P1462 通往奥格瑞玛的道路

    洛谷 题意:要求在限定油耗内,求最小花费的最大值. 求最小值最大很容易想到二分答案.所以我们往二分的方向去想. 我们二分一个费用,然后要保证到终点时满足限定油耗,所以跑最短路. 不过松弛条件要改一下: ...

随机推荐

  1. [CF11D]A Simple Task 题解

    题解 我们从最简单的思路开始考虑,首先看到题目发现\(n\)非常小,于是很容易想到状态压缩. 我们考虑比较直觉的状态,f[i][j][k]表示以i为起点,当前在j,之前去过的点状态为k的简单环的方案数 ...

  2. PKUWC2020爆零记

    抱歉,这么晚才更. 事实是:我都没有去 所以爆零了 QwQ

  3. 【gym102394B】Binary Numbers(DP)

    题意:From https://blog.csdn.net/m0_37809890/article/details/102886956 思路: 可以发现转移就是右上角的一个区间前缀和 std只要开1倍 ...

  4. 【Leetcode】二进制求和

    解题思路: 1. 首先在两个字符串前面补‘0’,使它们等长.否则要一直监督操作是否超出两个字符串的索引. 2. 从后向前遍历所有位数,同位相加.字符相加,利用ASCII码,字符在内部都用数字表示,我们 ...

  5. Spring Boot教程(十二)整合elk(1)

    elk 简介 Elasticsearch是个开源分布式搜索引擎,它的特点有:分布式,零配置,自动发现,索引自动分片,索引副本机制,restful风格接口,多数据源,自动搜索负载等. Logstash是 ...

  6. bestcoder#9--1001--Lotus and Characters

    Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 262144/131072 K (Java/Others) 问题描述 Lotus有nn种字母, ...

  7. select * from (XXXXX)[字符]——写法解析

    步骤:1.先执行括号里的语句:查询 select id from three ,将查询出来的数据作为一个结果集 取名为 a2.然后 再 select * from a 查询a ,将 结果集a 全部查询 ...

  8. PHP mac localhost 环境下发送邮件

    转载自:http://mabblog.com/blog/2011/09/lion-smtp-postfix-relay-and-dreamhost/ When developing web-apps ...

  9. python之正则匹配match:search findall

    match:从开头位置匹配,只匹配一次,开头匹配不上,则不继续匹配 a,b,\w+ match(a,"abcdef") 匹配a >>> re.match(&quo ...

  10. HDU6534 Chika and Friendly Pairs(莫队,树状数组)

    HDU6534 Chika and Friendly Pairs 莫队,树状数组的简单题 #include<bits/stdc++.h> using namespace std; cons ...