Educational Codeforces Round 51 (Rated for Div. 2) F - The Shortest Statement 倍增LCA + 最短路
emmm, 比赛的时候没有想到如何利用非树边。
其实感觉很简单。。
对于一个询问答案分为两部分求:
第一部分:只经过树边,用倍增就能求出来啦。
第二部分:经过至少一条非树边, 如果经过一个树边那么必定经过其两个端点,暴力的求出这些端点为起始点的最短路。
#include<bits/stdc++.h>
#define LL long long
#define fi first
#define se second
#define mk make_pair
#define PII pair<int, int>
#define PLI pair<LL, int>
using namespace std; const int N = 2e5 + ;
const int inf = 0x3f3f3f3f;
const LL INF = 0x3f3f3f3f3f3f3f3f;
const int mod = 1e9 + ; int n, m, tot, cnt, head[N], f[N][], d[N], depth[N];
LL cost[N][], dis[][N];
bool vis[N]; struct Edge {
int from, to, w, nx;
} edge[N << ]; void add(int u, int v, int w) {
edge[tot].from = u;
edge[tot].to = v;
edge[tot].w = w;
edge[tot].nx = head[u];
head[u] = tot++;
} void Dij(int S, LL d[N]) {
memset(d, INF, N * sizeof(LL));
priority_queue<PLI, vector<PLI>, greater<PLI> > que;
d[S] = ; que.push(mk(, S)); while(!que.empty()) {
int u = que.top().se;
LL dis = que.top().fi; que.pop();
if(dis > d[u]) continue;
for(int i = head[u]; ~i; i = edge[i].nx) {
int v = edge[i].to, w = edge[i].w;
if(dis + w < d[v]) {
d[v] = dis + w;
que.push(mk(d[v], v));
}
}
}
} void dfs(int u, int fa, int w, int deep) {
vis[u] = true; depth[u] = deep;
f[u][] = fa; cost[u][] = w;
for(int j = ; j < ; j++) {
f[u][j] = f[f[u][j-]][j-];
cost[u][j] = cost[f[u][j-]][j-] + cost[u][j-];
}
for(int i = head[u]; ~i; i = edge[i].nx) {
int v = edge[i].to;
if(v == fa) continue;
else if(vis[v]) {
d[cnt++] = u; d[cnt++] = v;
} else dfs(v, u, edge[i].w, deep + );
}
} int getLCA (int u, int v){
if(depth[u] < depth[v]) swap(u, v);
for(int j = ; j >= ; j--)
if(depth[u] - depth[v] >= ( << j))
u = f[u][j]; for(int j = ; j >= ; j--)
if(f[u][j] != f[v][j])
u = f[u][j], v = f[v][j];
return u == v ? u : f[u][];
} LL getDis(int u, int v) {
LL ans = ;
for(int j = ; j >= ; j--)
if(depth[u] - depth[v] >= ( << j))
ans += cost[u][j], u = f[u][j];
return ans;
} int main() {
memset(head, -, sizeof(head));
scanf("%d%d", &n, &m);
for(int i = ; i <= m; i++) {
int u, v, w;
scanf("%d%d%d", &u, &v, &w);
add(u, v, w); add(v, u, w);
}
dfs(, , , );
sort(d, d + cnt);
cnt = unique(d, d + cnt) - d; for(int i = ; i < cnt; i++) Dij(d[i], dis[i]); int q; scanf("%d", &q);
while(q--) {
int u, v, lca;
scanf("%d%d", &u, &v);
lca = getLCA(u, v);
LL ans = getDis(u, lca) + getDis(v, lca);
for(int i = ; i < cnt; i++) ans = min(ans, dis[i][u] + dis[i][v]);
printf("%lld\n", ans);
}
return ;
} /*
*/
Educational Codeforces Round 51 (Rated for Div. 2) F - The Shortest Statement 倍增LCA + 最短路的更多相关文章
- 【 Educational Codeforces Round 51 (Rated for Div. 2) F】The Shortest Statement
[链接] 我是链接,点我呀:) [题意] [题解] 先处理出来任意一棵树. 然后把不是树上的边处理出来 对于每一条非树边的点(最多21*2个点) 在原图上,做dijkstra 这样就能处理出来这些非树 ...
- Codeforces Educational Codeforces Round 44 (Rated for Div. 2) F. Isomorphic Strings
Codeforces Educational Codeforces Round 44 (Rated for Div. 2) F. Isomorphic Strings 题目连接: http://cod ...
- Educational Codeforces Round 71 (Rated for Div. 2)-F. Remainder Problem-技巧分块
Educational Codeforces Round 71 (Rated for Div. 2)-F. Remainder Problem-技巧分块 [Problem Description] ...
- Educational Codeforces Round 51 (Rated for Div. 2) G. Distinctification(线段树合并 + 并查集)
题意 给出一个长度为 \(n\) 序列 , 每个位置有 \(a_i , b_i\) 两个参数 , \(b_i\) 互不相同 ,你可以进行任意次如下的两种操作 : 若存在 \(j \not = i\) ...
- Educational Codeforces Round 51 (Rated for Div. 2)
做了四个题.. A. Vasya And Password 直接特判即可,,为啥泥萌都说难写,,,, 这个子串实际上是忽悠人的,因为每次改一个字符就可以 我靠我居然被hack了???? %……& ...
- Educational Codeforces Round 51 (Rated for Div. 2) The Shortest Statement
题目链接:The Shortest Statement 今天又在群里看到一个同学问$n$个$n$条边,怎么查询两点直接最短路.看来这种题还挺常见的. 为什么最终答案要从42个点的最短路(到$x,y$) ...
- CodeForces Educational Codeforces Round 51 (Rated for Div. 2)
A:Vasya And Password 代码: #include<bits/stdc++.h> using namespace std; #define Fopen freopen(&q ...
- The Shortest Statement(Educational Codeforces Round 51 (Rated for Div.2)+最短路+LCA+最小生成树)
题目链接 传送门 题面 题意 给你一张有\(n\)个点\(m\)条边的联通图(其中\(m\leq n+20)\),\(q\)次查询,每次询问\(u\)与\(v\)之间的最短路. 思路 由于边数最多只比 ...
- Educational Codeforces Round 50 (Rated for Div. 2) F - Relatively Prime Powers(数学+容斥)
题目链接:http://codeforces.com/contest/1036/problem/F 题意: 题解:求在[2,n]中,x != a ^ b(b >= 2 即为gcd)的个数,那么实 ...
随机推荐
- php curl使用ss代理
1.安装 ss,过程略 2.ss 配置文件 { "server":"x.x.x.x", #你的 ss 服务器 ip "server_port" ...
- bzoj 1513 POI2006 Tet-Tetris 3D 二维线段树+标记永久化
1511: [POI2006]OKR-Periods of Words Time Limit: 5 Sec Memory Limit: 64 MBSubmit: 351 Solved: 220[S ...
- 高并发大容量NoSQL解决方案探索
大数据时代,企业对于DBA也提出更高的需求.同时,NoSQL作为近几年新崛起的一门技术,也受到越来越多的关注.本文将基于个推SRA孟显耀先生所负责的DBA工作,和大数据运维相关经验,分享两大方向内容: ...
- 分块+二分,统计对数 CDOJ
http://acm.uestc.edu.cn/#/problem/show/1157 数列(seq) Time Limit: 3000/1000MS (Java/Others) Memory ...
- errno错误号含义
errno0 : Success errno1 : Operation not permitted errno2 : No such file or directory errno3 : No suc ...
- (一)Hadoop1.2.1安装——单节点方式和单机伪分布方式
Hadoop1.2.1安装——单节点方式和单机伪分布方式 一. 需求部分 在Linux上安装Hadoop之前,需要先安装两个程序: 1)JDK 1.6(或更高版本).Hadoop是用Java编写的 ...
- PhotoSwipe 图片浏览插件使用方法
一.简介 PhotoSwipe 是专为移动触摸设备设计的相册/画廊.兼容所有iPhone.iPad.黑莓6+,以及桌面浏览器.底层实现基于HTML/CSS/JavaScript,是一款免费开源的相册产 ...
- JSON 为王,为什么 XML 会慢慢淡出人们的视野?
目前全球信息基础设施的特点是,拥有大量的数据交换格式.这一点也不奇怪.互联网几乎已经老了,而“物联网”及“大数据”正从概念走进现实.但我仍然相信,在这一领域还有一股较强的历史趋势,推动 JSON 数据 ...
- asp.net实现access数据库分页
最近在编程人生上看到篇文章很有感触,觉得人生还是要多奋斗.今天给大家贡献点干货. <divclass="page"id="ctrlRecordPage"& ...
- python初步学习-面向对象之类(一)
python 面向对象 python 从设计之初就已经是一门面向对象的语言,正因为如此,在python中创建一个类和对象是很容易的. 对象对象奇数简介 类(Class): 用于描述具有相同的属性和方法 ...