题意

题目链接

题意:给出一张无向图,每次询问两点之间的最短路,满足$m - n <= 20$

$n, m, q \leqslant 10^5$

Sol

非常好的一道题。

首先建出一个dfs树。

因为边数-点数非常少,所以我们可以对于某些非树边特殊考虑。

具体做法是:对于非树边连接的两个点,暴力求出它们到所有点的最短路

对于询问的$(x, y)$

用树上的边,以及非树边连接的点到他们的最短路之和更新答案

由于边数的限制,非树边连接的点不会超过$2*(m - (n - 1)) = 42$个

#include<bits/stdc++.h>
#define Pair pair<int, int>
#define MP(x, y) make_pair(x, y)
#define fi first
#define se second
#define LL long long
using namespace std;
const int MAXN = 2 * 1e5 + 10;
inline int read() {char c = getchar(); int x = 0, f = 1;while(c < '0' || c > '9') {if(c == '-') f = -1; c = getchar();}while(c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar();return x * f;
}
int N, M, Q, head[MAXN], num = 0, vis[MAXN], fa[MAXN][21], dep[MAXN], happen[MAXN];
LL dis[50][MAXN], Tdis[MAXN];
vector<int> p;
struct Edge {LL u, v, w, f, nxt;
}E[MAXN];
inline void AddEdge(int x, int y, int z) {E[num] = (Edge) {x, y, z, 0, head[x]};head[x] = num++;
}
void dfs(int x, int _fa) {vis[x] = 1; dep[x] = dep[_fa] + 1;for(int i = head[x]; ~i; i = E[i].nxt) {int to = E[i].v;if(vis[to]) continue;E[i].f = E[i ^ 1].f = 1;Tdis[to] = Tdis[x] + (LL)E[i].w;fa[to][0] = x;dfs(to, x);}
}
void Dij(int x, int id) {memset(dis[id], 0x7f, sizeof(dis[id])); dis[id][x] = 0;memset(vis, 0, sizeof(vis));priority_queue<Pair> q; q.push(MP(0, x));while(!q.empty()) {int p = q.top().se; q.pop();if(vis[p]) continue;for(int i = head[p]; ~i; i = E[i].nxt) {int to = E[i].v;if(dis[id][to] > dis[id][p] + E[i].w && (!vis[to])) dis[id][to] = dis[id][p] + E[i].w, q.push(MP(-dis[id][to], to));}}
}
void Pre() {for(int j = 1; j <= 20; j++)for(int i = 1; i <= N; i++)fa[i][j] = fa[fa[i][j - 1]][j - 1];
}
int lca(int x, int y) {if(dep[x] < dep[y]) swap(x, y);for(int i = 20; i >= 0; i--)if(dep[fa[x][i]] >= dep[y]) x = fa[x][i];if(x == y) return x;for(int i = 20; i >= 0; i--)if(fa[x][i] != fa[y][i])x = fa[x][i], y = fa[y][i];return fa[x][0];
}
main() {
//    freopen("a.in", "r", stdin);memset(head, -1, sizeof(head));N = read(); M = read();for(int i = 1; i <= M; i++) {int x = read(), y = read(), z = read();AddEdge(x, y, z);AddEdge(y, x, z);}dfs(1, 0);for(int i = 0; i < num; i++) if(!E[i].f) {if(!happen[E[i].u]) p.push_back(E[i].u), happen[E[i].u] = 1;if(!happen[E[i].v]) p.push_back(E[i].v), happen[E[i].v] = 1;}for(int i = 0; i < p.size(); i++) Dij(p[i], i);Pre();int Q = read();while(Q--) {int x = read(), y = read();LL ans = Tdis[x] + Tdis[y] - 2 * Tdis[lca(x, y)];for(int i = 0; i < p.size(); i++) ans = min(ans, dis[i][x] + dis[i][y]);cout << ans << endl;}return 0;
}

转载于:https://www.cnblogs.com/zwfymqz/p/9688315.html

cf1051F. The Shortest Statement(最短路)相关推荐

  1. Codeforces.1051F.The Shortest Statement(最短路Dijkstra)

    题目链接 先随便建一棵树. 如果两个点(u,v)不经过非树边,它们的dis可以直接算. 如果两个点经过非树边呢?即它们一定要经过该边的两个端点,可以直接用这两个点到 u,v 的最短路更新答案. 所以枚 ...

  2. 图论 ---- F. The Shortest Statement (最短路的性质 + 任意两点间最短路 + 图转树)

    题目链接 题目大意: 给你一个nnn个点mmm条边的无向图,就是动态询问任意两点间的最短路 n,m∈[1,1e5],m−n≤20n,m\in[1,1e5],m-n\leq20n,m∈[1,1e5],m ...

  3. Educational Codeforces Round 51: F. The Shortest Statement(最短路+LCA)

    F. The Shortest Statement 题意: n个点m条边(m≤n+20)的无向连通图,Q次询问,每次求出给定两点的最短路 思路: 将题意转换一下,给你一棵n个节点的树,并且这个树上还有 ...

  4. 【Codeforces】1051F. The Shortest Statement【MST+LCA+最短路】

    F. The Shortest Statement [题目描述] 传送门 [题解] 题目也说了,重点是m-n<=20,我们就可以先跑最小生成树,最后剩下最多21条边,对着44个端点(包括起点和终 ...

  5. The Shortest Statement CodeForces - 1051F LCA+最短路

    太弱了... 一开始看到题感觉是跑一个最小生成树在上边进行LCA就行了,但是发现过不了样例,然后就是就想到了之前做过类似做法的题目,就是非生成树上的边最多只有21条,然后就那些边记录下来,通过每一条边 ...

  6. 图论复习——最小生成树MST

    知识点 MST的构造 Boruvka算法常用于解决这类问题:给你n个点,每个点有点权,任意两个点之间有边权,边权为两个点权用过某种计算方式得出,求最小生成树.动图 MST上的确定性和存在性问题 最小生 ...

  7. 像童话一样学习OSPF原理

    可以把整个网络(一个自治系统AS)看成一个王国,这个王国可以分成几个 区(area),现在我们来看看区域内的某一个人(你所在的机器root)是怎样得到一张 世界地图(routing table)的. ...

  8. 【HDOJ图论题集】【转】

    1 =============================以下是最小生成树+并查集====================================== 2 [HDU] 3 1213 How ...

  9. 一系列图论问题[转]

    =============================以下是最小生成树+并查集====================================== [HDU] 1213 How Many ...

最新文章

  1. C++中的const关键字(zz)
  2. 规范-编码规范总结(微信分销系统)
  3. python自定义分页器()转自https://www.cnblogs.com/yuanchenqi/articles/7652353.html
  4. win7装xp双系统_联智通达什么系统装工控电脑好_搜狐汽车
  5. case的执行顺序 嵌套使用
  6. 如何插入8bit量化节点(tensorflow)
  7. python 列表解析式_python列表解析式,字典解析式,集合解析式和生成器
  8. input type=image图片按钮具有提交功能
  9. 罗技Ghub配置文件压枪编程——仅供学习
  10. 基于Dijkstra算法和KM算法的网约车订单分配问题
  11. edk2中的全局变量gST和gBS
  12. 多玩网总裁李学凌:在腾讯阴影下
  13. 使用IAR和BSL下载程序至MSP430F2122
  14. 【微信辅助】疫情当前,python帮你找出朋友圈的武汉朋友给予关怀
  15. 怎样写一篇文章 施工中~
  16. vue3+Echart
  17. 【Nodejs】Nodejs入门必知
  18. 向日葵橙色调色Lr预设分享
  19. 【修改Windows系统的网络名称】
  20. 公文中需要特别注意的格式规范

热门文章

  1. 教你用树莓派打造一个家庭影院
  2. UML--核心元素之包
  3. spring融合activitymq-all启动报错的解决办法
  4. 简易调用及实例化视图
  5. Objective-c 类的继承 方法重写 方法重载
  6. SCOM 2012知识分享-21:无代理管理
  7. [IE编程] 如何获得IE版本号
  8. suid shell
  9. how to come in an investnent bank team
  10. 如何快速完成整理笔记?