L2-043 龙龙送外卖(计算节点深度)

传送门

解题思路

最优解情况下的龙龙一定是停在最深点,否则,会产生额外开销(往回走产生的),而对于其它点,我们需要走过它们的深度的2倍

因此,只需要计算出所有外卖点的深度,然后从所有的外卖点中找到最深点,由于最深点可能有多个,不如记最深的深度为max_d,这个过程中我们要统计出

走了多少条边,记为total_edges,由于我们最终需要的是边而非深度,例如一个深度为3的点,从原点到该点经过的边数为2,所以最后的结果等于
总边数×2 \(-\)(max_d - 1),因为除了从起点到最深点的这一条边没有返回,其他所有边都走过两遍。

  1. 用dfs函数+记忆化搜索来计算深度
int get_depth(int u)
{
if(u == -1) return 0;
if(depht[u]) return depth[u];
depth[u] = get_depth(parent[u]) + 1;
return depth[u];
}

ac✅️代码

#include<iostream>
#include<cstring>
using namespace std;
int parent[100010];
int depth[100010];
bool vis[100010];

int get_depth(int u )
{
	if(u == -1) return 0;

	if(depth[u]) return depth[u];
	
	depth[u] = get_depth(parent[u]) + 1;
	
	return depth[u];
 	
}

int main()
{
	
	memset(parent,-1,sizeof parent);
	
	int n,m;
	cin>>n>>m;
	int root = 0;
	for(int i = 1; i <= n ; i++)
	{
		int x;cin>>x;
		if(x == -1) root = i;
		else parent[i] = x;
		
	}
	
	vis[root] = true;
	
	int total_edges = 0;
	int max_d = -1;
	
	for(int i = 1 ; i <= m ; i++) 
	{
		int add;cin>>add;
		
		int d = get_depth(add) - 1;
		max_d = max(max_d,d);
		
		while(!vis[add])
		{
			total_edges ++;
			vis[add] = true;
			add = parent[add];
			
		}
		cout<<total_edges * 2 - max_d<<endl;
	}
	
	return 0;
}
posted @ 2026-03-19 17:47  shuiwangrenjia  阅读(189)  评论(0)    收藏  举报