题目链接

分析:

  还是很明白的题意,直接分析问题,首先,这一题真的是给spfa用武之地,m比n大不超过20,但是这并不能使暴力不t,我们考虑一下如何改进一下,我们这样想,这个图只比它的生成树多最多21条边,而树上的最短路有是那么的容易(lca),我们可以先求出在树上两个点之间的最短路,可是非树边也很有可能通过啊,怎么办呢?我们可以这样想,通过至少一个非树边与只通过树边是对立的,也就是说除了只通过非树边的都通过树边,而只通过树边的很好求,下面我们来思考如何求通过至少一个非树边的路径。

  如果通过至少一个非树边,那么一定通过这个边的两个顶点那么就好办了,最多一共有42个顶点在非树边两边,直接枚举通过每一个就好了(当然要提前处理出这些顶点的单元最短路)。

  还有,这题spfa好像是比dij快(m-n<=20)。

代码(dij)

#include <cstdio>
#include <queue>
#include <cstring>
using namespace std;
const int maxn=1e5+;
struct E{
int to;
int next;
long long val;
int f;
E(){
f=;
}
}ed[maxn*];
int head[maxn];
int tot;
void J(int a,int b,long long c){
tot++;
ed[tot].to=b;
ed[tot].val=c;
ed[tot].next=head[a];
head[a]=tot;
}
int vis[maxn];
int t[maxn][];
long long va[maxn][];
int js;
int a[maxn];
int b[maxn];
long long c[maxn];
int de[maxn];
void Dfs(int x,int fa,int id){
de[x]=de[fa]+;
t[x][]=fa;
va[x][]=ed[id].val;
for(int i=;i<=;i++){
t[x][i]=t[t[x][i-]][i-];
va[x][i]=va[x][i-]+va[t[x][i-]][i-];
}
vis[x]=;
for(int i=head[x];i;i=ed[i].next){
if(ed[i].to==fa||ed[i].f)
continue;
if(vis[ed[i].to]){
ed[i].f=ed[i%?(i+):(i-)].f=;
js++;
a[js]=x;
b[js]=ed[i].to;
c[js]=ed[i].val;
continue;
}
Dfs(ed[i].to,x,i);
}
}
long long dis[][maxn];
int vis2[maxn];
int ha;
struct Node{
int x;
long long dis;
Node(){
}
Node(int a,long long b){
x=a;
dis=b;
}
friend bool operator < (Node a,Node b){
return a.dis>b.dis;
}
};
priority_queue<Node> q;
void dij(int s){
memset(vis2,,sizeof(vis2));
ha++;
dis[ha][s]=;
q.push(Node(s,));
while(!q.empty()){
Node js=q.top();
q.pop();
if(vis2[js.x])
continue;
vis2[js.x]=;
for(int i=head[js.x];i;i=ed[i].next)
if(dis[ha][ed[i].to]>dis[ha][js.x]+ed[i].val){
dis[ha][ed[i].to]=dis[ha][js.x]+ed[i].val;
q.push(Node(ed[i].to,dis[ha][ed[i].to]));
}
}
}
long long lca(int x,int y){
long long ans=;
if(de[x]<de[y])
swap(x,y);
int k=de[x]-de[y];
int ji=;
while(k){
if(k&){
ans+=va[x][ji];
x=t[x][ji];
}
k>>=;
ji++;
}
if(x==y)
return ans;
for(int i=;i>=;i--)
if(t[x][i]!=t[y][i]){
ans+=va[x][i];
ans+=va[y][i];
x=t[x][i];
y=t[y][i];
}
ans+=va[x][]+va[y][];
return ans;
}
long long Min(long long a,long long b){
return a>b?b:a;
}
int main(){
memset(dis,0x3f,sizeof(dis));
int n,m;
scanf("%d%d",&n,&m);
int js1,js2;
long long js3;
for(int i=;i<=m;i++){
scanf("%d%d%lld",&js1,&js2,&js3);
J(js1,js2,js3);
J(js2,js1,js3);
}
Dfs(,,);
for(int i=;i<=js;i++){
dij(a[i]);
dij(b[i]);
}
int q;
scanf("%d",&q);
for(int i=;i<=q;i++){
scanf("%d%d",&js1,&js2);
long long p=lca(js1,js2);
for(int j=;j<=*js;j++)
p=Min(dis[j][js1]+dis[j][js2],p);
printf("%lld\n",p);
}
return ;
}

The Shortest Statement,题解的更多相关文章

  1. CF1051F The Shortest Statement 题解

    题目 You are given a weighed undirected connected graph, consisting of n vertices and m edges. You sho ...

  2. 【题解】Luogu CF1051F The Shortest Statement

    原题传送门:CF1051F The Shortest Statement 题目大意,给你一个稀疏图,q次查询,查询两点之间距离 边数减点小于等于20 这不是弱智题吗,23forever dalao又开 ...

  3. Codeforces 1051E Vasya and Big Integers&1051F The Shortest Statement

    1051E. Vasya and Big Integers 题意 给出三个大整数\(a,l,r\),定义\(a\)的一种合法的拆分为把\(a\)表示成若干个字符串首位相连,且每个字符串的大小在\(l, ...

  4. codeforces 1051F The Shortest Statement

    题目链接:codeforces 1051F The Shortest Statement 题意:\(q\)组询问,求任意两点之间的最短路,图满足\(m-n\leq 20\) 分析:一开始看这道题:fl ...

  5. The Shortest Statement CodeForces - 1051F(待测试)

    #include <iostream> #include <cstdio> #include <sstream> #include <cstring> ...

  6. Educational Codeforces Round 51 (Rated for Div. 2) F - The Shortest Statement 倍增LCA + 最短路

    F - The Shortest Statement emmm, 比赛的时候没有想到如何利用非树边. 其实感觉很简单.. 对于一个询问答案分为两部分求: 第一部分:只经过树边,用倍增就能求出来啦. 第 ...

  7. CF 1051 F. The Shortest Statement

    F. The Shortest Statement http://codeforces.com/contest/1051/problem/F 题意: n个点,m条边的无向图,每次询问两点之间的最短路. ...

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

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

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

  10. 题解 CF1051F 【The Shortest Statement】

    这道题思路比较有意思,第一次做完全没想到点子上... 看到题目第一反应是一道最短路裸题,但是数据范围1e5说明完全不可能. 这个时候可以观察到题目给出了一个很有意思的条件,就是说边最多比点多20. 这 ...

随机推荐

  1. js数据劫持 Object.defineProperty() 作用

    原生js Object.defineProperty() 作用 假设我们有一个obj对象,我们要给他设置一个name属性会这么做 Object.defineProperty()也可以设置对象属性 这个 ...

  2. iOS -程序启动原理和UIApplication的介绍

    一.UIApplication 简介       (1)UIApplication对象是应用程序的象征,一个UIApplication对象就代表一个应用程序. (2)每一个Application都有自 ...

  3. Vue —— VueX精讲(1)

    大纲 这一讲我们最主要的就是学习vue中的数据管理VueX,这个是一个大杀器 一.回顾一些Promise相关的东西 Promise 有几个比较重要的方法,最重要的还是有一个叫做all的方法,这个也是非 ...

  4. docker中mongdb常用操作

    一.进入 --使用本地命令行查看 docker exec -it mongos bash

  5. iOSdelegate、Notification、block区别

    1.delegate与block一般用于1对1的通信交互.delegate需先定义好协议方法,代理对象实现协议方法且需要建立代理关系才可以通信. 2.block使用简洁,如果通信事件较多,建议使用de ...

  6. 其他函数-web_get_int_property

    用于记录http响应的信息.这个函数在调试脚本的常用,但是在实际压力测试中请将这些注释 使用这个函数可以获取到的信息有: 1.HTTP_INFO_RETURN_CODE:返回HTTP响应码 2.HTT ...

  7. fiddler修改请求参数

    1.打开fiddler ,点击界面左侧左侧底部 2.此图标为before request请求(修改请求参数时,设置这个,可以修改请求参数) 3..再次点击该按钮,将图标切换到下图after respo ...

  8. 单例模式的DCL方式,您不可不知道的知识点

    单例模式的DCL是一种比较好的单例实现方式,面试中被问及的频率非常高,考察的方式也多种多样.这里简单整理了一下,这里面的每一个点最好都能够做到烂熟于心: 1 public class Test { 2 ...

  9. yii2.0AR两表联查

    首先,建两个关联表. 表一 -- Table structure for article -- ---------------------------- DROP TABLE IF EXISTS `a ...

  10. Java并发编程(05):悲观锁和乐观锁机制

    本文源码:GitHub·点这里 || GitEE·点这里 一.资源和加锁 1.场景描述 多线程并发访问同一个资源问题,假如线程A获取变量之后修改变量值,线程C在此时也获取变量值并且修改,两个线程同时并 ...