F - The Shortest Statement

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 + 最短路的更多相关文章

  1. 【 Educational Codeforces Round 51 (Rated for Div. 2) F】The Shortest Statement

    [链接] 我是链接,点我呀:) [题意] [题解] 先处理出来任意一棵树. 然后把不是树上的边处理出来 对于每一条非树边的点(最多21*2个点) 在原图上,做dijkstra 这样就能处理出来这些非树 ...

  2. 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 ...

  3. Educational Codeforces Round 71 (Rated for Div. 2)-F. Remainder Problem-技巧分块

    Educational Codeforces Round 71 (Rated for Div. 2)-F. Remainder Problem-技巧分块 [Problem Description] ​ ...

  4. Educational Codeforces Round 51 (Rated for Div. 2) G. Distinctification(线段树合并 + 并查集)

    题意 给出一个长度为 \(n\) 序列 , 每个位置有 \(a_i , b_i\) 两个参数 , \(b_i\) 互不相同 ,你可以进行任意次如下的两种操作 : 若存在 \(j \not = i\) ...

  5. Educational Codeforces Round 51 (Rated for Div. 2)

    做了四个题.. A. Vasya And Password 直接特判即可,,为啥泥萌都说难写,,,, 这个子串实际上是忽悠人的,因为每次改一个字符就可以 我靠我居然被hack了???? %……& ...

  6. Educational Codeforces Round 51 (Rated for Div. 2) The Shortest Statement

    题目链接:The Shortest Statement 今天又在群里看到一个同学问$n$个$n$条边,怎么查询两点直接最短路.看来这种题还挺常见的. 为什么最终答案要从42个点的最短路(到$x,y$) ...

  7. CodeForces Educational Codeforces Round 51 (Rated for Div. 2)

    A:Vasya And Password 代码: #include<bits/stdc++.h> using namespace std; #define Fopen freopen(&q ...

  8. The Shortest Statement(Educational Codeforces Round 51 (Rated for Div.2)+最短路+LCA+最小生成树)

    题目链接 传送门 题面 题意 给你一张有\(n\)个点\(m\)条边的联通图(其中\(m\leq n+20)\),\(q\)次查询,每次询问\(u\)与\(v\)之间的最短路. 思路 由于边数最多只比 ...

  9. 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)的个数,那么实 ...

随机推荐

  1. JSP2 特性

    JSP2 新特性 1.直接配置 JSP 属性 2.表达式语言 3.简化的自定义标签 API 4.Tag 文件语法 如果要使用 JSP2 语法,web.xml 文件必须使用 Servlet2.4 以上版 ...

  2. [LeetCode] 27. Remove Element ☆

    Given an array and a value, remove all instances of that value in place and return the new length. D ...

  3. Eclipse错误笔记!

    1.ERROR: JDWP Unable to get JNI 1.2 environment, jvm->GetEnv() return code = -2   JDWP exit error ...

  4. linux ll 命令参数详解

    linux ll和Linuxls 的区别 可看 http://www.cnblogs.com/jxhd1/p/6548449.html 用法:ls [选项]... [文件]... 列出 FILE 的信 ...

  5. ubuntu11下安装文件

    1.ubuntu11下安装.run文件 首先右键单击这个文件,在properties-permissions那里选择允许以程序执行(打钩Allow executing file as program) ...

  6. 5、Linux操作系统介绍

    1操作系统的作用·是现代计算机系统中最基本和最重要的系统软件·是配置在计算机硬件上的第一层软件,是对硬件系统的首次扩展·主要作用是管理好硬件设备,并为用户和应用程序提供一个简单的接口,以便于使用·而其 ...

  7. windows程序设计.第一个windos程序

    Windows程序设计(第5版) windows程序需要调用API. 第一个Windows程序 /*HelloMsg.c -- Displays "Hello World!" in ...

  8. three.js轨道控制器OrbitControls.js

    https://blog.csdn.net/qq_37338983/article/details/78575333 文章地址

  9. B2旅游签证记

    先去https://ceac.state.gov/ceac/,选择DS-160表格,在线申请登记个人信息 ,选择大事馆“CHINA BEIJING”和验证码,点 Start an Applicatio ...

  10. 最小的Django应用

    创建一个hello.py   内容如下: import sys from django.conf import settings # 设置 settings.configure( DEBUG = Tr ...