题解 CF1051F 【The Shortest Statement】
这道题思路比较有意思,第一次做完全没想到点子上。。。
看到题目第一反应是一道最短路裸题,但是数据范围1e5说明完全不可能。
这个时候可以观察到题目给出了一个很有意思的条件,就是说边最多比点多20。
这有什么用呢?
那么我们大胆猜想,可否将整个图划分为21条边(连接最多42个点)和一颗树?(极限情况)
如果这样的话,对于任意的两个节点uv,它们之间的最短路只有两种情况:
这两个点都在树上。所以说最短路必然是u->lca(u,v)->v。
不是上面那种情况。这个时候肯定会有连到外面那21个边。我们暴力枚举一下就可以了。
到这里思路就完全出来了,我们先把不属于树的点挑出来,对每一个都跑一下最短路。
然后对于每一组询问判断一下属于哪一种情况就可以了。
AC代码如下:
37657ms 67712kb
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<queue>
using namespace std;
namespace StandardIO{
template<typename T>inline void read(T &x){
x=0;T f=1;char c=getchar();
for(;c<'0'||c>'9';c=getchar())if(c=='-')f=-1;
for(;c>='0'&&c<='9';c=getchar())x=x*10+c-'0';
x*=f;
}
template<typename T>inline void write(T x){
if(x<0)putchar('-'),x*=-1;
if(x>=10)write(x/10);
putchar(x%10+'0');
}
}
using namespace StandardIO;
namespace Solve{
#define int long long
const int N=100100;
const int INF=2147483647;
int n,m,p;
int cnt;
int head[N];
struct node{
int to,val,next;
}edge[N<<1];
template<typename T>inline void add(T a,T b,T c){
edge[++cnt].to=b,edge[cnt].val=c,edge[cnt].next=head[a],head[a]=cnt;
}
struct qnode{
int key,val;
bool operator < (qnode x)const{
return val>x.val;
}
};
int top;
int vis[N],fa[N][23],dist[N],dep[N],q[N];
int dis[50][N];
inline void dfs(int now,int father){
vis[now]=1,fa[now][0]=father;
for(register int i=head[now];i;i=edge[i].next){
int to=edge[i].to;
if(to==father)continue;
if(vis[to])q[++top]=now,q[++top]=to;
else{
dep[to]=dep[now]+1,dist[to]=dist[now]+edge[i].val;
dfs(to,now);
}
}
}
template<typename T>inline T lca(T x,T y){
if(dep[x]<dep[y])swap(x,y);
for(register int i=19;i>=0;--i){
if(dep[fa[x][i]]>=dep[y])x=fa[x][i];
}
if(x==y)return x;
for(register int i=19;i>=0;--i){
if(fa[x][i]!=fa[y][i]){
x=fa[x][i],y=fa[y][i];
}
}
return fa[x][0];
}
inline void dijkstra(int now){
memset(dis[now],63,sizeof(dis[now]));
memset(vis,0,sizeof(vis));
priority_queue<qnode>Q;
dis[now][q[now]]=0;
Q.push((qnode){q[now],0});
while(!Q.empty()){
int tmp=Q.top().key;Q.pop();
if(vis[tmp])continue;
vis[tmp]=1;
for(register int i=head[tmp];i;i=edge[i].next){
int to=edge[i].to;
if(!vis[to]&&dis[now][tmp]+edge[i].val<dis[now][to]){
dis[now][to]=dis[now][tmp]+edge[i].val;
Q.push((qnode){to,dis[now][to]});
}
}
}
}
inline void solve(){
read(n),read(m);
for(register int i=1;i<=m;++i){
int a,b,c;
read(a),read(b),read(c);
add(a,b,c),add(b,a,c);
}
dep[1]=1,dfs(1,0);
for(register int j=1;j<=19;++j){
for(register int i=1;i<=n;++i){
fa[i][j]=fa[fa[i][j-1]][j-1];
}
}
sort(q+1,q+top+1);top=unique(q+1,q+top+1)-q-1;
for(register int i=1;i<=top;++i)dijkstra(i);
read(p);
while(p--){
int x,y;
read(x),read(y);
int ans=dist[x]+dist[y]-2*dist[lca(x,y)];
for(register int i=1;i<=top;++i)ans=min(ans,dis[i][x]+dis[i][y]);
write(ans),putchar('\n');
}
}
}
using namespace Solve;
#undef int
int main(){
solve();
}
题解 CF1051F 【The Shortest Statement】的更多相关文章
- 【题解】Luogu CF1051F The Shortest Statement
原题传送门:CF1051F The Shortest Statement 题目大意,给你一个稀疏图,q次查询,查询两点之间距离 边数减点小于等于20 这不是弱智题吗,23forever dalao又开 ...
- CF1051F The Shortest Statement 题解
题目 You are given a weighed undirected connected graph, consisting of n vertices and m edges. You sho ...
- cf1051F. The Shortest Statement(最短路/dfs树)
You are given a weighed undirected connected graph, consisting of nn vertices and mm edges. You shou ...
- [CF1051F]The Shortest Statement
题目大意:给定一张$n$个点$m$条有权边的无向联通图,$q$次询问两点间的最短路 $n\le100000$,$m\le100000$,$1\le100000$,$m$-$n\le20$. 首先看到$ ...
- [CF1051F]The Shortest Statement (LCA+最短路)(给定一张n个点m条有权边的无向联通图,q次询问两点间的最短路)
题目:给定一张n个点m条有权边的无向联通图,q次询问两点间的最短路 n≤100000,m≤100000,m-n≤20. 首先看到m-n≤20这条限制,我们可以想到是围绕这个20来做这道题. 即如果我们 ...
- cf1051F. The Shortest Statement(最短路)
题意 题目链接 题意:给出一张无向图,每次询问两点之间的最短路,满足$m - n <= 20$ $n, m, q \leqslant 10^5$ Sol 非常好的一道题. 首先建出一个dfs树. ...
- CF1051F The Shortest Statement Dijkstra + 性质分析
动态询问连通图任意两点间最短路,单次询问. 显然,肯定有一些巧妙地性质(不然你就发明了新的最短路算法了233)有一点很奇怪:边数最多只比点数多 $20$ 个,那么就可以将这个图看作是一个生成树,上面连 ...
- Codeforces 1051E Vasya and Big Integers&1051F The Shortest Statement
1051E. Vasya and Big Integers 题意 给出三个大整数\(a,l,r\),定义\(a\)的一种合法的拆分为把\(a\)表示成若干个字符串首位相连,且每个字符串的大小在\(l, ...
- [CF1051F]The Shortest Statement_堆优化dij_最短路树_倍增lca
The Shortest Statement 题目链接:https://codeforces.com/contest/1051/problem/F 数据范围:略. 题解: 关于这个题,有一个重要的性质 ...
- codeforces 1051F The Shortest Statement
题目链接:codeforces 1051F The Shortest Statement 题意:\(q\)组询问,求任意两点之间的最短路,图满足\(m-n\leq 20\) 分析:一开始看这道题:fl ...
随机推荐
- echarts在vue里面使用,以及基础配置。
基础的图表和基础的配置. 效果图如下: 1.安装图表依赖包:npm install echarts 2.在main.js里面 引入echarts import echarts from 'echart ...
- 【codeforces 719E】Sasha and Array
[题目链接]:http://codeforces.com/contest/719/problem/E [题意] 给你一个数列,有两种操作1 l r x 给[l,r]区间上的数加上x, 2 l r 询问 ...
- mysql 在Linux 配置 主从同步
一.主服务器相关配置 1.创建同步账户并指定服务器地址 [root@localhost ~]mysql -uroot -pmysql>use mysqlmysql>grant replic ...
- [SharePoint][SharePoint Designer 入门经典]Chapter13 客户端JavaScript编程
1.创建客户对象模型的页面 2.使用CAML从SPS中取得数据 3.创建更新删除列表项目 4.为ribbon添加项目
- [using_microsoft_infopath_2010]Chapter 14高级话题
本章提要: 1.剖析表单逻辑 2.从多个表单中合并数据 3.重新连接XML表单到XSN模板文件 4.在repeating table中设置默认值 5.离线填写表单的权衡
- Loadrunner得到server參数
首先你得确定你所监视的server与你的測试机是在同一个局域网内, 监控windows系统: 1.监视连接前的准备工作 1)进入被监视windows系统.开启下面二个服务Remote ...
- nor flash 和nand flash 傻傻分不清楚
nor flash和nand flash差别 学习嵌入式有一段时间了,刚接触nor和nand时非常是迷惑.非要逼我写一篇博客才干记清楚. 首先他们都是存储设备.统称叫做flash memory.导致他 ...
- 关于ZipOupputStream添加压缩包常见问题
其实园子压缩解压缩的方法很多,ZipOupputStream这个类的说明很多,我这边也是从网上找的代码,但是我在压缩的时候遇到了常见的两个问题,第一个就是压缩的时候读取压缩包报该压缩包已经在另一个进程 ...
- 百度编辑器图片在线流量返回url改动
百度编辑器中返回的是我们server中的url,有时并非我们须要的,比方图文编辑中.我想在线浏览上传过的图片 ,那么我返回的应该是腾讯server上面的url.这样才不会被腾讯的过滤器过来掉,全部我们 ...
- javascript中的闭包以及闭包应用
闭包简单理解就是能够读取其他函数内部变量的函数,而在javascript中只有内部函数可以读取函数的内部变量,所以我们学习javascript时可以这样理解,函数A中嵌套了一个函数B,然后我们用函数B ...