列表

详情


NC23482. 小A的最短路

描述

小A这次来到一个景区去旅游,景区里面有N个景点,景点之间有N-1条路径。小A从当前的一个景点移动到下一个景点需要消耗一点的体力值。但是景区里面有两个景点比较特殊,它们之间是可以直接坐观光缆车通过,不需要消耗体力值。而小A不想走太多的路,所以他希望你能够告诉它,从当前的位置出发到他想要去的那个地方,他最少要消耗的体力值是多少。

输入描述

第一行一个整数N代表景区的个数。
接下来N-1行每行两个整数u,v代表从位置u到v之间有一条路径可以互相到达。
接下来的一行两个整数U,V表示这两个城市之间可以直接坐缆车到达。
接下来一行一个整数Q,表示有Q次询问。
接下来的Q行每行两个整数x,y,代表小A的位置在x,而他想要去的地方是y。

输出描述

示例1

输入:

4
1 2
1 3
2 4
3 4
2
1 3
3 4

输出:

1
0

原站题解

上次编辑到这里,代码来自缓存 点击恢复默认模板

C++(g++ 7.5.0) 解法, 执行用时: 1790ms, 内存消耗: 50188K, 提交时间: 2023-04-17 17:05:52

#include<iostream>
#include<vector>
#include<algorithm>
#define endl '\n'
using namespace std;
const int N=5e5+10,M=20;
vector<int> e[N],dep(N);
int n,m;
int x,y;
int f[N][M];
void dfs(int u,int fa){
    dep[u]=dep[fa]+1;
    f[u][0]=fa;
    for(int i=1;i<=19;i++)
        f[u][i]=f[f[u][i-1]][i-1];

    for(auto &x:e[u])
        if(x!=fa)dfs(x,u);
}
inline int lca(int a,int b){
    if(dep[a]<dep[b])swap(a,b);
    for(int i=19;i>=0;i--)if(dep[f[a][i]]>=dep[b])a=f[a][i];
    if(a==b)return a;
    for(int i=19;i>=0;i--)
        if(f[a][i]!=f[b][i])
            a=f[a][i],b=f[b][i];
    return f[a][0];
}
inline int dis(int a,int b){
    return dep[a]+dep[b]-2*dep[lca(a,b)];
}
int main(){
    ios::sync_with_stdio(false);
    cin.tie(nullptr);cout.tie(nullptr);
    cin>>n;
    int a,b;
    for(int i=1;i<n;i++){
        cin>>a>>b;
        e[a].push_back(b);
        e[b].push_back(a);
    }
    dfs(1,0);
    cin>>x>>y;
    cin>>m;
    for(int i=1;i<=m;i++){
        cin>>a>>b;
        cout<<min(dis(a,b),min(dis(a,x)+dis(b,y),dis(a,y)+dis(b,x)))<<endl;
    }
    return 0;
}

C++11(clang++ 3.9) 解法, 执行用时: 1876ms, 内存消耗: 50560K, 提交时间: 2019-05-23 21:36:06

#include<bits/stdc++.h>
using namespace std;
#define maxn 1000005
int n,m,q,i,j,k,s,t,h[maxn],ne[maxn],p[maxn],d[maxn],f[maxn][20];
int LCA(int x,int y){
	int i;
	if(d[x]>d[y]) swap(x,y);
	if(d[x]!=d[y]) for(i=19;~i;i--) if(d[y]-d[x]>>i&1) y=f[y][i];
	if(x!=y){
		for(i=19;~i;i--)
		{
			if(f[x][i]!=f[y][i])
			{
				x=f[x][i];
				y=f[y][i];
			}
		}
		x=f[x][0];
	}
	return x;
}
int dis(int x,int y){
	return d[x]+d[y]-(d[LCA(x,y)]<<1);
}
void dfs(int x){
	for(int i=1;i<20;i++) f[x][i]=f[f[x][i-1]][i-1];
	for(int i=h[x];i;i=ne[i]) if(p[i]!=f[x][0])
	{
		f[p[i]][0]=x;
		d[p[i]]=d[x]+1;
		dfs(p[i]);
	}
}
int main(){
	scanf("%d",&n);
	for(i=1;i<n;i++){
		scanf("%d%d",&j,&k);
		p[++m]=k;
		ne[m]=h[j];
		h[j]=m;
		p[++m]=j;
		ne[m]=h[k];
		h[k]=m;
	}
	dfs(1);
	scanf("%d%d%d",&s,&t,&q);
	while(q--){
		scanf("%d%d",&i,&j);
		printf("%d\n",min(dis(i,j),min(dis(i,s)+dis(j,t),dis(i,t)+dis(j,s))));
	}
	return 0;
}

上一题