海南某神秘211校赛 不要再来这么多猫猫了

猫猫题

解题思路

这题刚开始的时候我不知道双向图怎么遍历树,那个时候dfs函数还不太会用,经过百万年筹谋积蓄,现在已经可以独立写出来了,算是整理题目的收获吧,包括自己对dfs函数的理解也越来越深。

双向邻接表,我使用了一个vis数组来给走过的点做标记,有效遍历每个结点。题目要求的是连续的猫猫,所以一旦中途遇到了一个没有猫猫的点,当前路径的猫猫值清零。题目说了1是起点,那就从1开始

有关dfs函数的思考

在dfs函数中,我们通常会采取两种情况修改变量,一个是全局变量,当我们修改了全局变量的时候,在dfs函数调用之后一定要手动回溯;还有一种是值传递,也就是作为函数参数列表里的变量,这种情况下,不需要我们去想回溯的事情,它会自动回溯。比如本题我的代码采用的就是值传递

ac✅️代码

#include<iostream>
#include<vector>

using namespace std;
int n,m;
vector<int> road[200010];
int cnt[200010];
bool vis[200010];

int ans ;

void dfs(int u,int nums)
{
	
	if(nums > m) return ;//剪枝
	
	if(road[u].size() == 1 && u != 1 && nums <= m)
	{
		ans++;
		return ;
	}
		
	for(int v : road[u])
	{
		if(!vis[v])
		{
			vis[v] = true;
			if(cnt[v])
			{			
				dfs(v , nums + cnt[v]);
			}			
			else dfs(v,0);
		}
	}
}

int main()
{
	vis[1] = true;
	cin>>n>>m;
	for(int i = 1 ; i <= n ; i++)
	{
		cin>>cnt[i];
	}
	
	for(int i = 1 ; i < n ; i++)
	{
		int l,r;
		cin>>l>>r;
		road[l].push_back(r);
		road[r].push_back(l);
	}
	
	dfs(1,cnt[1]);
	
	cout<<ans<<endl;
	
	
	return 0;
}
posted @ 2026-03-22 18:12  shuiwangrenjia  阅读(42)  评论(0)    收藏  举报