The Shortest Statement,题解
题目链接
分析:
还是很明白的题意,直接分析问题,首先,这一题真的是给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,题解的更多相关文章
- CF1051F The Shortest Statement 题解
题目 You are given a weighed undirected connected graph, consisting of n vertices and m edges. You sho ...
- 【题解】Luogu CF1051F The Shortest Statement
原题传送门:CF1051F The Shortest Statement 题目大意,给你一个稀疏图,q次查询,查询两点之间距离 边数减点小于等于20 这不是弱智题吗,23forever dalao又开 ...
- 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> ...
- Educational Codeforces Round 51 (Rated for Div. 2) F - The Shortest Statement 倍增LCA + 最短路
F - The Shortest Statement emmm, 比赛的时候没有想到如何利用非树边. 其实感觉很简单.. 对于一个询问答案分为两部分求: 第一部分:只经过树边,用倍增就能求出来啦. 第 ...
- CF 1051 F. The Shortest Statement
F. The Shortest Statement http://codeforces.com/contest/1051/problem/F 题意: n个点,m条边的无向图,每次询问两点之间的最短路. ...
- Educational Codeforces Round 51 (Rated for Div. 2) The Shortest Statement
题目链接:The Shortest Statement 今天又在群里看到一个同学问$n$个$n$条边,怎么查询两点直接最短路.看来这种题还挺常见的. 为什么最终答案要从42个点的最短路(到$x,y$) ...
- 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 ...
- 题解 CF1051F 【The Shortest Statement】
这道题思路比较有意思,第一次做完全没想到点子上... 看到题目第一反应是一道最短路裸题,但是数据范围1e5说明完全不可能. 这个时候可以观察到题目给出了一个很有意思的条件,就是说边最多比点多20. 这 ...
随机推荐
- 蒲公英 · JELLY技术周刊 Vol.10 为什么你还不使用 TypeScript
登高远眺 天高地迥,觉宇宙之无穷 基础技术 直播延迟?为什么流媒体直播的延迟那么高 随着通信技术的发展,视频点播.直播业务也逐渐兴起.在这些业务形态中,流媒体技术扮演着重要的角色.但在实际使用中,即便 ...
- 2020/06/06 JavaScript高级程序设计 面向对象的程序设计
ECMAScript虽然是一种面向对象的语言,但是他没有类的概念.所以他的对象也与其他语言中的对象有所不同. ECMA-262定义对象:一组没有特定顺序的值. 6.1 理解对象 创建对象的方法: 1. ...
- Crypto++ AES 加密解密流程
// aesdemo.cpp : 定义控制台应用程序的入口点. // #include <stdio.h>#include <tchar.h>#include <iost ...
- css3中的@font-face你真的了解吗
css3中的自定义字体方法@font-face @font-face属性可以让我们自定义网站字体属性,然后引用到想要应用该字体的元素上. 基本语法: @font-face { font-family: ...
- 开窗函数_ROW_NUMBER() / RANK() / DENSE_RANK() / NTILE() ------4个排名函数训练_1
排名函数(训练,其实从SQL2005时就已经被引入) /*SQL Server 2012从零开始学_7.8 排序函数*/ --DROP TABLE fruits GO Create table fr ...
- SpringMVC的url-pattern配置及原理剖析
SpringMVC的url-pattern配置及原理剖析 xml里面配置标签: <!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc./ ...
- python_lesson2 多进程探索 (multiprocessing包)
进程池 进程池 (Process Pool)可以创建多个进程.这些进程就像是随时待命的士兵,准备执行任务(程序).一个进程池中可以容纳多个待命的士兵. import multiproces ...
- Android学习笔记数组资源文件
在android中我们可以通过数组资源文件,定义数组元素. 数组资源文件是位于values目录下的 array.xml <?xml version="1.0" encodin ...
- ca71a_c++_指向函数的指针_通过指针调用函数txwtech
/*ca71a_c++_指向函数的指针_通过指针调用函数用typedef简化函数指针的定义简化前: bool(*pf)(const string&, const string &); ...
- 12.实战交付一套dubbo微服务到k8s集群(5)之交付dubbo-monitor到K8S集群
dubbo-monitor官方源码地址:https://github.com/Jeromefromcn/dubbo-monitor 1.下载dubbo-monitor源码并解压 [root@hdss7 ...