AtCoder Beginner Contest 148 F.Playing Tag on Tree
Problem Statement
(略)
Output
Print the number of moves Aoki will perform before the end of the game.
Sample Input 1
5 4 1
1 2
2 3
3 4
3 5
Sample Output 1
2
Sample Input 2
5 4 5
1 2
1 3
1 4
1 5
Sample Output 2
1
Sample Input 3
2 1 2
1 2
Sample Output 3
0
Sample Input 4
9 6 1
1 2
2 3
3 4
4 5
5 6
4 7
7 8
8 9
Sample Output 4
5
题意比较简单,但是比较难下手,看了题解才知道要找的结点满足离Aoki最远且Takahashi到达该结点比Aoki早即可,就跑了两遍BFS,最后遍历更新一遍即可,AC代码如下:
#include <bits/stdc++.h>
#define maxn 100005
using namespace std;
typedef long long ll;
vector<int>G[maxn];
int step1[maxn],step2[maxn];
int vis1[maxn],vis2[maxn];
int n,s1,s2,u,v;
void bfs(int k){
if(k==s1){
queue<int>q;
q.push(k);
step1[k]=0;
vis1[k]=1;
while(!q.empty()){
int a=q.front();
q.pop();
for(int b:G[a]){
if(!vis1[b]) {
step1[b]=step1[a]+1;
vis1[b]=1;
q.push(b);
}
}
}
}
else if(k==s2){
queue<int>q;
q.push(k);
step2[k]=0;
vis2[k]=1;
while(!q.empty()){
int a=q.front();
q.pop();
for(int b:G[a]){
if(!vis2[b]) {
step2[b]=step2[a]+1;
vis2[b]=1;
q.push(b);
}
}
}
}
}
int main(){
memset(vis1,0,sizeof(vis1));
memset(vis2,0,sizeof(vis2));
memset(step1,0,sizeof(step1));
memset(step2,0,sizeof(step2));
cin>>n>>s1>>s2;
for(int i=0;i<n-1;i++){
scanf("%d%d",&u,&v);
G[u].push_back(v);
G[v].push_back(u);
}
bfs(s1);
bfs(s2);
int ans=0;
for(int i=1;i<=n;i++){
if(step1[i]<step2[i]) ans=max(ans,step2[i]);
}
cout<<ans-1;
return 0;
}