海南某神秘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;
}

浙公网安备 33010602011771号