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. mysql 特殊符号

    1.完全等于 <=> mysql> select null <=> null; +---------------+ | null <=> null | +-- ...

  2. spring自带工具类

    在spring-core.jar包中,org.springframework.util package下有很多工具类,这些工具类十分具有参考意义.

  3. php大文件上传支持断点上传

    文件夹数据库处理逻辑 publicclass DbFolder { JSONObject root; public DbFolder() { this.root = new JSONObject(); ...

  4. luogu 4725 【模板】多项式对数函数(多项式 ln)

    $G(x)=ln(A(x))$ $G'(x)=ln'(A(x))A'(x)=\frac{A'(x)}{A(x)}$     由于求导和积分是互逆的,所以对 $G$ 求积分,即 $G(x)=\int\f ...

  5. HDU1575--Tr A(矩阵快速幂)

    Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Submission(s) ...

  6. 从Java中的length和length()开始

    1.在没有IDE自动补齐的情况下,怎样得到数组的长度?怎样得到字符串的长度? int[] arr = new int[3]; System.out.println(arr.length);//leng ...

  7. SQL Server CDC最佳实践

    企业核心业务系统oltp的数据需要通过ETL同步到数据仓库,原始的ETL流程通过定制化从SQL Server中进行数据抽取,经过生产环境的监控,发现ETL过程的query会对生产系统造成额外负载.于是 ...

  8. final finalize finally throw throws try catch

    什么是finalize()方法 finalize()方法什么时候被调用 参见网址 析构函数(finalization)的目的是什么 final 和 finalize 的区别 final以下参见网址 f ...

  9. pyhton2与pyhton3切换

    ubuntu中默认的Python版本是Python2.X,但是现在Python的最新版本是Python3.X. 那么怎么修改ubutun系统默认的Python解释器呢? 如果没有安装,则使用以下命令安 ...

  10. EMQ插件通过HTTP连接认证服务器实现认证

    需求 在EMQ中添加认证插件,将到来的MQTT连接的ClientID.UserName.Password通过HTTP协议发送到认证服务器,用返回的数据决定是否允许该连接: 在连接时和断开时向服务器发送 ...