首页 > 其他分享 >P10289 [GESP样题 八级] 小杨的旅游 题解

P10289 [GESP样题 八级] 小杨的旅游 题解

时间:2024-04-14 18:12:22浏览次数:30  
标签:int 题解 bfs fa 传送门 P10289 push GESP dis

题目简述

给定一棵树,节点之间的距离为 $1$,树上有 $k$ 个传送门,可以从一个传送门瞬间传送到另一个传送门,有 $q$ 此询问,问 $u$ 和 $v$ 之间的最短距离是多少。

题目分析

首先考虑没有传送门,我们可以直接求两个点的 LCA,再用高度容斥计算即可。

如果有传送门,那么有用与不用两种选择,如果用的话,那么最优的方法一定是 $u$ 到离它最近的传送门的距离,再加上 $v$ 到离它最近的传送门的距离,这个可以直接用 bfs 预处理,最后在与不用的法案比较一下。

代码

#include<bits/stdc++.h>
using namespace std;
const int N=2e5+10;
int n,k,Q,deep[N],fa[N][40],dis[N]; 
vector<int> G[N];
queue<int> q;
void dfs(int u,int father)
{
	deep[u]=deep[father]+1;
	fa[u][0]=father;
	for(int i=1;i<=30;i++)
	    fa[u][i]=fa[fa[u][i-1]][i-1];
	for(int v:G[u])
	    if(v!=father) dfs(v,u);
	return;
}
int lca(int u,int v)
{
	if(deep[u]<deep[v])
	    swap(u,v);
	int temp=deep[u]-deep[v];
	for(int i=0;i<=30;i++)
	    if(temp>>i&1)
		    u=fa[u][i];
	if(u==v) return u;
	for(int i=30;i>=0;i--)
	    if(fa[u][i]!=fa[v][i])
		    u=fa[u][i],v=fa[v][i];
	return fa[u][0];
}
void bfs()
{
	while(!q.empty())
	{
		int u=q.front();q.pop();
		for(int v:G[u])
		    if(dis[v]==dis[0])
		        dis[v]=dis[u]+1,q.push(v);
	}
	return;
}
int main()
{
	ios::sync_with_stdio(false);
    cin.tie(0);
    cin>>n>>k>>Q;
    memset(dis,0x3f,sizeof dis);
    for(int x=0,y=0,i=1;i<n;i++)
    {
    	cin>>x>>y;
    	G[x].push_back(y);
    	G[y].push_back(x);
	}
	dfs(1,0);
	for(int x=0,i=1;i<=k;i++)
	    cin>>x,q.push(x),dis[x]=0;
    bfs();
	for(int x=0,y=0,i=1;i<=Q;i++)
	    cin>>x>>y,cout<<min(dis[x]+dis[y],deep[x]+deep[y]-2*deep[lca(x,y)])<<"\n";
	return 0;
}

标签:int,题解,bfs,fa,传送门,P10289,push,GESP,dis
From: https://www.cnblogs.com/zhuluoan/p/18134475

相关文章

  • 【官方题解】Codeforces Round 939 (Div. 2)
    CodeforcesRoundAyachiNeneSolutions(div.2)A.Nene'sGameIdea:[user:Otomachi_Una]Solution不难发现如果一个人初始位置\(p\geqa_1\),那么必然会在有限次回合当中被踢出。答案即为\(\min(n,a_1-1)\)。B.NeneandtheCardGameIdea:[user:Otomachi_Una]Hint......
  • [暴力题解系列+正经题解]好数
    好数虽然不是13号考的那批人,但是还是扔一个暴力题解在这里。首先数据范围\(n\le10^7\),就算纯粹暴力去做也只是\(O(nlogn)\),也就是直接从1到n去枚举。秉持着暴力就是要优化细节的精神,对题目进行一个分析,发现无论如何,个位数必须是奇数,否则必然不满足条件,那么优化手段就显而易见了......
  • P8741 [蓝桥杯 2021 省 B] 填空问题 题解
    题目传送门试题A:空间【解析】本题考察计算机存储的基础知识,只要掌握空间存储的换算方法,就能够算出答案。【程序】#include<bits/stdc++.h>usingnamespacestd;intmain(){printf("%d\n",256*8/32*1024*1024);return0;}【答案】67108864......
  • P8679 [蓝桥杯 2019 省 B] 填空问题 题解
    题目传送门试题A:组队【解析】本题是一道经典的DFS搜索题,每次对各号位的选手进行DFS,找到各号位上有成绩的选手时再进行进一步搜索即可。【程序】#include<bits/stdc++.h>usingnamespacestd;intteam[20][6];intmax_sum;boolvis[20];voiddfs(intu,intsu......
  • P9686 Judg. 题解
    题目传送门一道简单模拟。这道题最简单的方法就是直接在for循环中判断题目给出状态是否为AC,如果不是则输出当前\(i\)的值,否则就不输出。#include<bits/stdc++.h>usingnamespacestd;constintMAXN=1e5+10;intn;stringa[MAXN];intmain(){ scanf("%......
  • P9517 drink 题解
    题目传送门这道题考场上用的查找做的。先用一个结构体分别表示firstlast,然后进行查找即可,两个for循环分别计算出first和last,最后计算它们的差值。(注意,计算差值时要加1)然后你就会发现一个问题:只有\(90\)分。所以我们来思考一下哪里出现了问题。你会发现:如果全都是......
  • P8741 [蓝桥杯 2021 省 B] 填空问题 题解
    题目传送门试题A:空间【解析】本题考察计算机存储的基础知识,只要掌握空间存储的换算方法,就能够算出答案。【程序】#include<bits/stdc++.h>usingnamespacestd;intmain(){printf("%d\n",256*8/32*1024*1024);return0;}【答案】67108864......
  • [题解]P3413 萌数
    P3413萌数先打出暴搜代码,参数有\(pos,limit,hui\),其中bool类型的\(hui\)表示到当前是否有回文。暴搜代码中加入了一个剪枝:if(!limit&&hui)returnpow10[pos];,这个!limit很重要,我就是因为这个没加,暴搜代码都调了半天。然后就是if(pos==0)returnhui;。我们还需要记录下填过的......
  • [题解]CF55D Beautiful Numbers
    CF55DBeautifulNumbers打出暴搜后有些茫然,不知道该怎么优化才好,看了题解才豁然开朗。简单说下暴搜的思路:参数有\(pos,limit,lcm,num\)。其中\(lcm\)表示到\(pos+1\)位,所有非\(0\)位的\(lcm\)是多少;\(num\)表示填到\(pos+1\)位的整个数是多少。然后在\(pos=0\)时判断\(lcm\)是......
  • [题解]CF1073E Zegment Sum
    CF1073ESegmentSum这道数位dp与其他不同的是,这个求的是满足要求的数的和,这种题型的题我们还没有做过。以前虽然做过一些求和或者求积的题,但都是求每个满足条件的数的数位和、二进制1的个数等等的和。而这道题是对\([L,R]\)中满足条件的数直接求和,这意味着基本不会有两个状态得......