cf1051F. The Shortest Statement(最短路)
题意
题目链接
题意:给出一张无向图,每次询问两点之间的最短路,满足$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(最短路)相关推荐
- Codeforces.1051F.The Shortest Statement(最短路Dijkstra)
题目链接 先随便建一棵树. 如果两个点(u,v)不经过非树边,它们的dis可以直接算. 如果两个点经过非树边呢?即它们一定要经过该边的两个端点,可以直接用这两个点到 u,v 的最短路更新答案. 所以枚 ...
- 图论 ---- F. The Shortest Statement (最短路的性质 + 任意两点间最短路 + 图转树)
题目链接 题目大意: 给你一个nnn个点mmm条边的无向图,就是动态询问任意两点间的最短路 n,m∈[1,1e5],m−n≤20n,m\in[1,1e5],m-n\leq20n,m∈[1,1e5],m ...
- Educational Codeforces Round 51: F. The Shortest Statement(最短路+LCA)
F. The Shortest Statement 题意: n个点m条边(m≤n+20)的无向连通图,Q次询问,每次求出给定两点的最短路 思路: 将题意转换一下,给你一棵n个节点的树,并且这个树上还有 ...
- 【Codeforces】1051F. The Shortest Statement【MST+LCA+最短路】
F. The Shortest Statement [题目描述] 传送门 [题解] 题目也说了,重点是m-n<=20,我们就可以先跑最小生成树,最后剩下最多21条边,对着44个端点(包括起点和终 ...
- The Shortest Statement CodeForces - 1051F LCA+最短路
太弱了... 一开始看到题感觉是跑一个最小生成树在上边进行LCA就行了,但是发现过不了样例,然后就是就想到了之前做过类似做法的题目,就是非生成树上的边最多只有21条,然后就那些边记录下来,通过每一条边 ...
- 图论复习——最小生成树MST
知识点 MST的构造 Boruvka算法常用于解决这类问题:给你n个点,每个点有点权,任意两个点之间有边权,边权为两个点权用过某种计算方式得出,求最小生成树.动图 MST上的确定性和存在性问题 最小生 ...
- 像童话一样学习OSPF原理
可以把整个网络(一个自治系统AS)看成一个王国,这个王国可以分成几个 区(area),现在我们来看看区域内的某一个人(你所在的机器root)是怎样得到一张 世界地图(routing table)的. ...
- 【HDOJ图论题集】【转】
1 =============================以下是最小生成树+并查集====================================== 2 [HDU] 3 1213 How ...
- 一系列图论问题[转]
=============================以下是最小生成树+并查集====================================== [HDU] 1213 How Many ...
最新文章
- C++中的const关键字(zz)
- 规范-编码规范总结(微信分销系统)
- python自定义分页器()转自https://www.cnblogs.com/yuanchenqi/articles/7652353.html
- win7装xp双系统_联智通达什么系统装工控电脑好_搜狐汽车
- case的执行顺序 嵌套使用
- 如何插入8bit量化节点(tensorflow)
- python 列表解析式_python列表解析式,字典解析式,集合解析式和生成器
- input type=image图片按钮具有提交功能
- 罗技Ghub配置文件压枪编程——仅供学习
- 基于Dijkstra算法和KM算法的网约车订单分配问题
- edk2中的全局变量gST和gBS
- 多玩网总裁李学凌:在腾讯阴影下
- 使用IAR和BSL下载程序至MSP430F2122
- 【微信辅助】疫情当前,python帮你找出朋友圈的武汉朋友给予关怀
- 怎样写一篇文章 施工中~
- vue3+Echart
- 【Nodejs】Nodejs入门必知
- 向日葵橙色调色Lr预设分享
- 【修改Windows系统的网络名称】
- 公文中需要特别注意的格式规范