Codeforces Round #321 (Div. 2) C. Kefa and Park(树+dfs)

https://codeforces.com/contest/580/problem/C

题目大意:
给定一棵树,这棵树总共有n个节点,自己家住在节点1(根节点);

每个节点都有一个标记a[i],标记为1就是这个地方有猫,0就表示没有;

每个叶子节点都是餐馆,我们想去最多数量的餐馆,但是我们不想走这条数量有连续>m个猫的路去餐馆。

问我们这样的餐馆数量有多少?
input 
4 1
1 1 0 0
1 2
1 3
1 4
output 
2
input 
7 1
1 0 1 1 0 0 0
1 2
1 3
2 4
2 5
3 6
3 7
output 
2

需要注意的点

  • 无向边:所以我们需要两端都建立边
  • 特判父节点:否则导致死循环;
  • 叶子节点只有它自己,根节点也有可能只有它自己,所以我们在判断叶子节点时,需要把根节点拉出来特判
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef pair<LL,LL> PII;
const LL MAXN=1e18;
const LL N=200200,M=2002;
LL n,m,a[N],ans=0;
vector<LL> g[N];
void dfs(LL idx,LL fa,LL sum,LL flag)
{
    if(sum>m) flag=1;//记得题目是要严格大于哦
    if(idx!=1&&g[idx].size()==1)//叶子节点,判断是否有误
    {
        if(flag==0) ans++;
        return ;
    }
    for(LL i=0;i<g[idx].size();i++)
    {
        if(g[idx][i]==fa) ;//判断父节点
        else
        {
            if(a[g[idx][i]]==0) dfs(g[idx][i],idx,0,flag);//当前数量标记可以重新填写
            else dfs(g[idx][i],idx,sum+1,flag);//当前数量继续递增
        }
    }
}
int main()
{
    cin.tie(0); cout.tie(0); ios::sync_with_stdio(false);
    LL T=1;
    //cin>>T;
    while(T--)
    {
        cin>>n>>m;
        for(LL i=1;i<=n;i++)
            cin>>a[i];
        for(LL i=1;i<n;i++)
        {
            LL v,w;
            cin>>v>>w;
            g[v].push_back(w);
            g[w].push_back(v);
        }
        dfs(1,-1,a[1],0);//从根节点开始,父节点为-1,数量为a[1],标记一下有没有产生过
        cout<<ans<<endl;
    }
    return 0;
}

嘻嘻,写出来了这题我好开心哇!

posted @ 2022-10-05 20:50  Vijurria  阅读(23)  评论(0编辑  收藏  举报