传送门:

这是一道bzoj权限题

Luogu团队题链接

解题思路

首先对于每一个点 \(x\) 预处理出 \(nr[x]\) 和 \(dis[x]\),分别表示离 \(x\) 最近的加油站以及该段距离。

这个过程可以用多源 \(\text{Dijkstra}\) 处理。

然后对于每一条原图中的边 \((u, v, w)\)(\(nr[u]\ne nr[v]\))

改为这样一条边:\((nr[u], nr[v], dis[u] + dis[v] + w)\)

然后只要离线用并查集维护一下连通性即可。

细节注意事项

  • 最短路不要写挂啊

参考代码

#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdlib>
#include <cstdio>
#include <cctype>
#include <cmath>
#include <ctime>
#include <queue>
#define rg register
#define pii pair < int, int >
using namespace std;
template < typename T > inline void read(T& s) {
s = 0; int f = 0; char c = getchar();
while (!isdigit(c)) f |= (c == '-'), c = getchar();
while (isdigit(c)) s = s * 10 + (c ^ 48), c = getchar();
s = f ? -s : s;
} const int _ = 200010;
const int __ = 400010; int tot, head[_], nxt[__], ver[__], w[__];
inline void Add_edge(int u, int v, int d)
{ nxt[++tot] = head[u], head[u] = tot, ver[tot] = v, w[tot] = d; } int q, n, m, k, c[_], vis[_], dis[_], nr[_];
struct node{ int u, v, d, id; }ask[_], g[__], e[__]; int ans[_]; inline bool cmp(const node& x, const node& y) { return x.d < y.d; } inline void Dijkstra() {
static priority_queue < pii > Q;
memset(dis, 0x3f, sizeof dis);
for (rg int i = 1; i <= k; ++i)
Q.push(make_pair(dis[c[i]] = 0, c[i])), nr[c[i]] = c[i];
while (!Q.empty()) {
int u = Q.top().second; Q.pop();
if (vis[u]) continue; vis[u] = 1;
for (rg int i = head[u]; i; i = nxt[i]) {
int v = ver[i];
if (dis[v] > dis[u] + w[i])
dis[v] = dis[u] + w[i], nr[v] = nr[u], Q.push(make_pair(-dis[v], v));
}
}
} int fa[_]; inline int findd(int x) { return fa[x] == x ? x : fa[x] = findd(fa[x]); } inline void merge(int x, int y) { fa[findd(x)] = findd(y); } int main() {
#ifndef ONLINE_JUDGE
freopen("in.in", "r", stdin);
#endif
read(n), read(k), read(m);
for (rg int i = 1; i <= k; ++i) read(c[i]);
for (rg int u, v, d, i = 1; i <= m; ++i)
read(u), read(v), read(d), Add_edge(u, v, d), Add_edge(v, u, d), g[i] = (node) { u, v, d };
Dijkstra();
int cnt = 0;
for (rg int u, v, i = 1; i <= m; ++i) {
u = g[i].u, v = g[i].v;
if (nr[u] != nr[v]) e[++cnt] = (node) { nr[u], nr[v], dis[u] + dis[v] + g[i].d };
}
read(q);
for (rg int i = 1; i <= q; ++i)
read(ask[i].u), read(ask[i].v), read(ask[i].d), ask[i].id = i;
sort(ask + 1, ask + q + 1, cmp);
sort(e + 1, e + cnt + 1, cmp);
for (rg int i = 1; i <= n; ++i) fa[i] = i;
for (rg int i = 1, j = 1; i <= q; ++i) {
while (j <= cnt && e[j].d <= ask[i].d) merge(e[j].u, e[j].v), ++j;
ans[ask[i].id] = findd(ask[i].u) == findd(ask[i].v);
}
for (rg int i = 1; i <= q; ++i) puts(ans[i] ? "TAK" : "NIE");
return 0;
}

完结撒花 \(qwq\)

最新文章

  1. c#-1 数据结构 定义相关 界面交互数据 Model层
  2. Android EditText输入格式设置
  3. android xml解析添加到listview中的问题
  4. Oracle中的不等于号
  5. c++一些问题总结
  6. 20141104--SQL,查询习题,约束
  7. (译)Node.js的 EventEmitter 教程
  8. JVM笔记5-对象的访问定位。
  9. 使用Ext JS,不要使用页面做组件重用,尽量不要做页面跳转
  10. Linux硬盘文件分析取证(SSH过的IP)
  11. LOJ #10084. 「一本通 3.3 练习 1」最小圈(二分+SPFA判负环)
  12. Oracle 表删除操作
  13. Extjs4.x 共享组件,写法
  14. Mysql-SqlServer区别
  15. @ControllerAdvice 拦截异常并统一处理(转载)
  16. 使用 Git 来备份 MySQL 数据库
  17. 现代web开发需要学习的15大技术
  18. 2016.9.9《Oracle查询优化改写技巧与案例》电子工业出版社一书中的技巧
  19. Java 基础,小数百分比两种方法
  20. Flask16 项目结构、flask_script插件

热门文章

  1. 【MySQL】外键的变种
  2. CDH搭建大数据集群(5.10.0)
  3. mui 监听 手机 物理返回键
  4. Vue-表单提交
  5. ASP.NET Core搭建多层网站架构【5-网站数据库实体设计及映射配置】
  6. 5_1 大理石在哪儿(UVa10474)&lt;排序与查找&gt;
  7. 第三方控件引起的&quot;类型Universe无法解析程序集&quot;的血案
  8. Python的 REPL 模式
  9. typo3 安装
  10. HDU1540 Turnal Warfare