传送门

Luogu

解题思路

注意到 \(m - n \le 20\) ,所以这其实是一个树上问题,非树边至多只有21条,那么我们就可以暴力地对每一个非树边所连接的点求一次单源最短路,然后每次询问时,先访问两点的树上距离,再尝试用非树边更新答案,取最小值输出即可。

细节注意事项

  • 最短路不要写挂就好

参考代码

#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdlib>
#include <cstdio>
#include <cctype>
#include <cmath>
#include <ctime>
#include <vector>
#include <queue>
#define rg register
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;
} typedef long long LL;
const int _ = 100010;
const int __ = 200010; int tot = 1, 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 n, m, q, f[22][_], dep[_];
int vis[_], mark[__], sign[_];
LL tdis[_], dis[50][_];
vector < int > vec; inline void dfs(int u) {
vis[u] = 1;
for (rg int i = head[u]; i; i = nxt[i]) {
int v = ver[i]; if (vis[v]) continue;
f[0][v] = u, dep[v] = dep[u] + 1;
tdis[v] = tdis[u] + (LL) w[i];
mark[i] = mark[i ^ 1] = 1, dfs(v);
}
} inline void calc() {
for (rg int i = 1; i <= 20; ++i)
for (rg int j = 1; j <= n; ++j)
f[i][j] = f[i - 1][f[i - 1][j]];
} inline int LCA(int x, int y) {
if (dep[x] < dep[y]) swap(x, y);
for (rg int i = 20; ~i; --i)
if (dep[f[i][x]] >= dep[y]) x = f[i][x];
if (x == y) return x;
for (rg int i = 20; ~i; --i)
if (f[i][x] != f[i][y]) x = f[i][x], y = f[i][y];
return f[0][x];
} inline void Dijkstra(int s, int p) {
static priority_queue < pair < LL, int > > Q;
memset(vis, 0, sizeof vis);
memset(dis[p], 0x7f, sizeof dis[p]);
dis[p][s] = 0, Q.push(make_pair(0, s));
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[p][v] > dis[p][u] + w[i])
dis[p][v] = dis[p][u] + w[i], Q.push(make_pair(-dis[p][v], v));
}
}
} inline LL solve(int x, int y) {
LL res = tdis[x] + tdis[y] - 2 * tdis[LCA(x, y)];
for (rg int i = 0; i < (int) vec.size(); ++i)
res = min(res, dis[i][x] + dis[i][y]);
return res;
} int main() {
#ifndef ONLINE_JUDGE
freopen("in.in", "r", stdin);
#endif
read(n), read(m);
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);
dfs(1), calc();
for (rg int i = 2; i <= tot; ++i)
if (!mark[i] && !sign[ver[i]])
vec.push_back(ver[i]), sign[ver[i]] = 1;
for (rg int i = 0; i < (int) vec.size(); ++i) Dijkstra(vec[i], i);
read(q); for (rg int x, y; q--; ) read(x), read(y), printf("%lld\n", solve(x, y));
return 0;
}

完结撒花 \(qwq\)

「CF1051F」The Shortest Statement的更多相关文章

  1. 题解 CF1051F 【The Shortest Statement】

    这道题思路比较有意思,第一次做完全没想到点子上... 看到题目第一反应是一道最短路裸题,但是数据范围1e5说明完全不可能. 这个时候可以观察到题目给出了一个很有意思的条件,就是说边最多比点多20. 这 ...

  2. 【题解】Luogu CF1051F The Shortest Statement

    原题传送门:CF1051F The Shortest Statement 题目大意,给你一个稀疏图,q次查询,查询两点之间距离 边数减点小于等于20 这不是弱智题吗,23forever dalao又开 ...

  3. 「译」forEach循环中你不知道的3件事

    前言 本文925字,阅读大约需要7分钟. 总括: forEach循环中你不知道的3件事. 原文地址:3 things you didn't know about the forEach loop in ...

  4. 「译」JUnit 5 系列:条件测试

    原文地址:http://blog.codefx.org/libraries/junit-5-conditions/ 原文日期:08, May, 2016 译文首发:Linesh 的博客:「译」JUni ...

  5. 「译」JUnit 5 系列:扩展模型(Extension Model)

    原文地址:http://blog.codefx.org/design/architecture/junit-5-extension-model/ 原文日期:11, Apr, 2016 译文首发:Lin ...

  6. JavaScript OOP 之「创建对象」

    工厂模式 工厂模式是软件工程领域一种广为人知的设计模式,这种模式抽象了创建具体对象的过程.工厂模式虽然解决了创建多个相似对象的问题,但却没有解决对象识别的问题. function createPers ...

  7. 「C++」理解智能指针

    维基百科上面对于「智能指针」是这样描述的: 智能指针(英语:Smart pointer)是一种抽象的数据类型.在程序设计中,它通常是经由类型模板(class template)来实做,借由模板(tem ...

  8. 「JavaScript」四种跨域方式详解

    超详细并且带 Demo 的 JavaScript 跨域指南来了! 本文基于你了解 JavaScript 的同源策略,并且了解使用跨域跨域的理由. 1. JSONP 首先要介绍的跨域方法必然是 JSON ...

  9. 「2014-5-31」Z-Stack - Modification of Zigbee Device Object for better network access management

    写一份赏心悦目的工程文档,是很困难的事情.若想写得完善,不仅得用对工具(use the right tools),注重文笔,还得投入大把时间,真心是一件难度颇高的事情.但,若是真写好了,也是善莫大焉: ...

随机推荐

  1. 并查集-G - 食物链

    G - 食物链 动物王国中有三类动物A,B,C,这三类动物的食物链构成了有趣的环形.A吃B, B吃C,C吃A.现有N个动物,以1-N编号.每个动物都是A,B,C中的一种,但是我们并不知道它到底是哪一种 ...

  2. JS高级---bind方法的使用

    bind方法的使用 //通过对象,调用方法,产生随机数 function ShowRandom() { //1-10的随机数 this.number = parseInt(Math.random() ...

  3. hfs 文件存储

    hfs 服务器上面的和本地拖上去的文件是同一个文件.对本地文件拖上去之后再修改,服务器文件也会修改.所以服务器要有一个自己的文件存放.

  4. wamp选择语言

    桌面右下角 右击绿色小图标 点击language选择chinese

  5. Vue - 表单修饰符

    .lazy 在默认情况下,v-model 在每次 input 事件触发后将输入框的值与数据进行同步 . 使用 lazy 修饰符,从而转变为使用 change 事件进行同步 <div id=&qu ...

  6. MongoDB C#驱动使用方法

    string connStr = ConfigurationManager.ConnectionStrings["MongoDBConnStr"].ConnectionString ...

  7. Common Subsequence Gym - 102307C 公共序列

    2019 ICPC Universidad Nacional de Colombia Programming Contest C D J   C. Common Subsequence 题意:给出长度 ...

  8. AcWing 872. 最大公约数

    #include <iostream> #include <algorithm> using namespace std; //辗转相除法 //a和b的最大公约数 = b和(a ...

  9. git 初次push

    1.本地仓库与远程仓库第一次同步时,一直同步不上 最后 git status ,发现有两个文件没提交 提交后再push即可 2.如果不行,再看一下其他情况

  10. JavaScript复习总结一(入门)

    总是执着想学各种框架,但忘了基础学好才最重要.每次打开菜鸟教程想重温基础内容,然后就像翻开英文字典,永远在abandon...还是需要做个笔记. 一来加深学习印象,二来等下次打开学习可以知道自己上次学 ...