问题 M: Playing Tag on Tree------------------------------思维(图论)

31 篇文章 0 订阅

题目描述
We have a tree with N vertices. The i-th edge connects Vertex Ai and Bi bidirectionally.
Takahashi is standing at Vertex u, and Aoki is standing at Vertex v.
Now, they will play a game of tag as follows:

  1. If Takahashi and Aoki are standing at the same vertex, the game ends. Otherwise, Takahashi moves to a vertex of his choice that is adjacent to his current vertex.
  2. If Takahashi and Aoki are standing at the same vertex, the game ends. Otherwise, Aoki moves to a vertex of his choice that is adjacent to his current vertex.
  3. Go back to step 1.
    Takahashi performs his moves so that the game ends as late as possible, while Aoki performs his moves so that the game ends as early as possible.
    Find the number of moves Aoki will perform before the end of the game if both Takahashi and Aoki know each other’s position and strategy.
    It can be proved that the game is bound to end.

Constraints
·2≤N≤105
·1≤u,v≤N
·u≠v
·1≤Ai,Bi≤N
·The given graph is a tree.
输入
Input is given from Standard Input in the following format:

N u v
A1 B1
:
AN−1 BN−1

输出
Print the number of moves Aoki will perform before the end of the game.
样例输入 Copy
【样例1】

5 4 1
1 2
2 3
3 4
3 5
【样例2】
5 4 5
1 2
1 3
1 4
1 5
【样例3】
2 1 2
1 2
【样例4】
9 6 1
1 2
2 3
3 4
4 5
5 6
4 7
7 8
8 9
样例输出 Copy
【样例1】

2
【样例2】
1
【样例3】
0
【样例4】
5
提示
样例1解释

If both players play optimally, the game will progress as follows:
·Takahashi moves to Vertex 3.
·Aoki moves to Vertex 2.
·Takahashi moves to Vertex 5.
·Aoki moves to Vertex 3.
·Takahashi moves to Vertex 3.
Here, Aoki performs two moves.

Note that, in each move, it is prohibited to stay at the current vertex.
题意:
给一棵树,x和y博弈,首先x在u点,y在v点,游戏结束条件是x和y重合,x先动,x希望游戏更晚结束,y希望游戏更早结束,求y在游戏结束前走的步数
解析:

设最终在点p处结束游戏 那么满足dist(p,u)<=dist(p,v)
因为x可以跑很远,y肯定要走x走过的路,自然y到p点就远了
所以取满足离y最远且x到达该结点比y早即可

由于x先动,所以我们要去dist(p,v)的最大值

#include<bits/stdc++.h> 
using namespace std;
const int N=1e5+1000;
vector<int> G[N];
int d[N],d1[N];
bool st[N];
int n,u,v,a,b;
void bfs1(int u,int d[])
{
	memset(st,false,sizeof st);
	queue<int> q;
	q.push(u);
	st[u]=true;
	d[u]=0;
	while(q.size())
	{
		int t=q.front();
		q.pop();
		for(int j: G[t])
		{
			if(j==t) continue;
			if(st[j]) continue;
			d[j]=d[t]+1;
			st[j]=true;
			q.push(j);
		}
	}
	
}
void bfs2(int u,int d1[])
{
	memset(st,false,sizeof st);
	queue<int> q;
	q.push(u);
	st[u]=true;
	d1[u]=0;
	while(q.size())
	{
		int t=q.front();
		q.pop();
		for(int j: G[t])
		{
			if(j==t) continue;
			if(st[j]) continue;
			d1[j]=d1[t]+1;
			st[j]=true;
			q.push(j);
		}
	}
	
}
int main()
{
	cin>>n>>u>>v;
	for(int i=0;i<n-1;i++)
	{
		cin>>a>>b;
		G[a].push_back(b);G[b].push_back(a);
	}
	bfs1(u,d);bfs2(v,d1);
	int ans=0;;
	for(int i=1;i<=n;i++)
	{
	//	cout<<d[i]<<" "<<d1[i]<<endl;
		if(d[i]<d1[i]) ans=max(ans,d1[i]);
	}
	cout<<ans-1<<endl;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值