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;
}
嘻嘻,写出来了这题我好开心哇!