CF 1051 F. The Shortest Statement
F. The Shortest Statement
http://codeforces.com/contest/1051/problem/F
题意:
n个点,m条边的无向图,每次询问两点之间的最短路。(m-n<=20)
分析:
dijkstra。
如果是一棵树,那么可以直接通过,dis[u]+dis[v]-dis[lca]*2来求。现在如果建出一棵树,那么非树边只有小于等于21条。
只经过树边的路径用上面的方式求出,考虑经过非树边的路径。
经过非树边(至少一条),那么一定经过了这条边的顶点,所以可以对顶点做一次最短路,如果询问u,v经过这个顶点,那么就是dis[u]+dis[v]。
代码:
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<iostream>
#include<cctype>
#include<set>
#include<vector>
#include<queue>
#include<map>
#define fi(s) freopen(s,"r",stdin);
#define fo(s) freopen(s,"w",stdout);
using namespace std;
typedef long long LL; inline int read() {
int x=,f=;char ch=getchar();for(;!isdigit(ch);ch=getchar())if(ch=='-')f=-;
for(;isdigit(ch);ch=getchar())x=x*+ch-'';return x*f;
} const LL INF = 1e18;
const int N = ; int head[N], nxt[N << ], to[N << ], len[N << ], En;
int f[N][], deth[N], tmp[], tot;
LL dis[N], d[][N];
int n, m;
bool vis[N]; void add_edge(int u,int v,int w) {
++En, to[En] = v, len[En] = w, nxt[En] = head[u], head[u] = En;
++En, to[En] = u, len[En] = w, nxt[En] = head[v], head[v] = En;
} #define pa pair<LL,int>
#define mp(a,b) make_pair(a,b)
priority_queue< pa, vector< pa >, greater< pa > > q; void Dijkstra(int id,int S) {
for (int i=; i<=n; ++i) dis[i] = INF, vis[i] = false;
dis[S] = ;
q.push(mp(, S));
while (!q.empty()) {
int u = q.top().second; q.pop();
if (vis[u]) continue;
vis[u] = true;
for (int i=head[u]; i; i=nxt[i]) {
int v = to[i];
if (dis[v] > dis[u] + len[i]) {
dis[v] = dis[u] + len[i];
q.push(mp(dis[v], v));
}
}
}
for (int i=; i<=n; ++i) d[id][i] = dis[i];
}
void dfs(int u,int fa) {
vis[u] = true;
f[u][] = fa;
deth[u] = deth[fa] + ;
for (int i=head[u]; i; i=nxt[i]) {
int v = to[i];
if (v == fa) continue;
if (vis[v]) tmp[++tot] = u, tmp[++tot] = v;
else dis[v] = dis[u] + len[i], dfs(v, u);
}
}
int LCA(int u,int v) {
if (deth[u] < deth[v]) swap(u, v);
int d = deth[u] - deth[v];
for (int i=; i>=; --i)
if (d & ( << i)) u = f[u][i];
if (u == v) return u;
for (int i=; i>=; --i)
if (f[u][i] != f[v][i])
u = f[u][i], v = f[v][i];
return f[u][];
}
int main() {
n = read(), m = read();
for (int i=; i<=m; ++i) {
int u = read(), v = read(), w = read();
add_edge(u, v, w);
} dfs(, );
for (int i=; i<=n; ++i) d[][i] = dis[i];
for (int j=; j<=; ++j)
for (int i=; i<=n; ++i) f[i][j] = f[f[i][j-]][j-];
sort(tmp + , tmp + tot + );
int lim = tot; tot = ;
for (int i=; i<=lim; ++i) if (tmp[tot] != tmp[i]) tmp[++tot] = tmp[i];
for (int i=; i<=tot; ++i) Dijkstra(i, tmp[i]); int Q = read();
while (Q --) {
int u = read(), v = read();
int t = LCA(u, v);
LL ans = d[][u] + d[][v] - * d[][t];
for (int i=; i<=tot; ++i)
ans = min(ans, d[i][u] + d[i][v]);
printf("%I64d\n",ans);
}
return ;
}
CF 1051 F. The Shortest Statement的更多相关文章
- Educational Codeforces Round 51 (Rated for Div. 2) F - The Shortest Statement 倍增LCA + 最短路
F - The Shortest Statement emmm, 比赛的时候没有想到如何利用非树边. 其实感觉很简单.. 对于一个询问答案分为两部分求: 第一部分:只经过树边,用倍增就能求出来啦. 第 ...
- Educational Codeforces Round 51 F. The Shortest Statement(lca+最短路)
https://codeforces.com/contest/1051/problem/F 题意 给一个带权联通无向图,n个点,m条边,q个询问,询问两点之间的最短路 其中 m-n<=20,1& ...
- CF_Edu.#51_Div.2_1051F_The Shortest Statement
F. The Shortest Statement time limit per test:4 seconds memory limit per test:256 megabytes input:st ...
- Codeforces 1051E Vasya and Big Integers&1051F The Shortest Statement
1051E. Vasya and Big Integers 题意 给出三个大整数\(a,l,r\),定义\(a\)的一种合法的拆分为把\(a\)表示成若干个字符串首位相连,且每个字符串的大小在\(l, ...
- codeforces 1051F The Shortest Statement
题目链接:codeforces 1051F The Shortest Statement 题意:\(q\)组询问,求任意两点之间的最短路,图满足\(m-n\leq 20\) 分析:一开始看这道题:fl ...
- The Shortest Statement CodeForces - 1051F(待测试)
#include <iostream> #include <cstdio> #include <sstream> #include <cstring> ...
- 【题解】Luogu CF1051F The Shortest Statement
原题传送门:CF1051F The Shortest Statement 题目大意,给你一个稀疏图,q次查询,查询两点之间距离 边数减点小于等于20 这不是弱智题吗,23forever dalao又开 ...
- CF 633 F. The Chocolate Spree 树形dp
题目链接 CF 633 F. The Chocolate Spree 题解 维护子数答案 子数直径 子数最远点 单子数最长直径 (最长的 最远点+一条链) 讨论转移 代码 #include<ve ...
- Educational Codeforces Round 51 (Rated for Div. 2) The Shortest Statement
题目链接:The Shortest Statement 今天又在群里看到一个同学问$n$个$n$条边,怎么查询两点直接最短路.看来这种题还挺常见的. 为什么最终答案要从42个点的最短路(到$x,y$) ...
随机推荐
- WebSphere Studio Application Developer 5.0 优化设置
公司有一个项目需要用到WebSphere Studio Application Developer 5.0 的开发环境,这个环境比较老,而且只能用JDK1.4. 项目开发的时候 总是报错: JVM t ...
- thinkphp5.0查询到的数据表中的路径是反斜杠导致无法正常显示图片怎么办?
添加到数据表中图片的路径有时会是反斜杠,这就导致了在url后面写路径的时候会识别不出来(不过src后面写路径就可以识别),所以就需要把路径中的反斜杠替换成正斜杠,代码如下: $datu = Db::q ...
- CF#538(div 2) C. Trailing Loves (or L'oeufs?) 【经典数论 n!的素因子分解】
任意门:http://codeforces.com/contest/1114/problem/C C. Trailing Loves (or L'oeufs?) time limit per test ...
- 分享一个可下拉刷新的ScrollView
原理:就是动态改变ScrollView header的margin实现 主要的代码: http://blog.csdn.net/swust_chenpeng/article/details/39289 ...
- iOS应用启动原理图解 及ARC强弱引用
iOS应用启动原理图解(红色箭头表示strong强引用,绿色箭头代表weak若引用) 只要将UI控件拖到Storyboard里控制器的大view上,Xcode会自动将这些控件以强引用的形式加入到sel ...
- iOS多语言设置
最近公司做的项目需要向国外推广,因此app需要添加相应的语言设置,为此整理记录下多语言设置的过程.如有不对的地方,欢迎各位大神指正.下面就详细介绍下设置的过程: 1.基本设置 第一步:首先在 项目工程 ...
- python人工智能爬虫系列:怎么查看python版本_电脑计算机编程入门教程自学
首发于:python人工智能爬虫系列:怎么查看python版本_电脑计算机编程入门教程自学 http://jianma123.com/viewthread.aardio?threadid=431 本文 ...
- 竞赛题解 - NOIP2018 保卫王国
\(\mathcal{NOIP2018}\) 保卫王国 - 竞赛题解 按某一个炒鸡dalao名曰 taotao 的话说: \(\ \ \ \ \ \ \ \ \ "一道sb倍增题" ...
- sysbench安装
sysbench安装 1.下载软件mkdir -p /usr/local/softwarecd /usr/local/softwaregit clone https://github.com/akop ...
- 如何创建systemd定时任务
1. 如何创建一个定时任务,通过systemd系统 1. 如何创建一个定时任务,通过systemd系统 1.1. systemd中的timer 1.2. 自定义定时任务 1.2.1. 具体步骤 1.2 ...