題意:一棵以1爲根的樹,樹上有些點是紅的。一個葉子是合法的當且僅當從根到它的路徑上出現的連續紅點個數不超過m。求有多少個葉子是合法的。
題解:很單純的dfs,注意判斷葉子結點的條件是,這點的父節點已被訪問(這個必須要有,不判斷一下父節點是否訪問過的話,在只有兩個節點的情況下會把根節點錯誤地當作葉子結點),且這個結點只有一個連向父節點的邊。
AC代碼:
#include <iostream>
#include <cstring>
#include <cstdio>
#include <string>
#include <map>
#include <vector>
#include <algorithm>
using namespace std;
typedef long long ll;
const int maxn=1e6+5;
int ans=0,n,m,red[maxn],mp[maxn],vis[maxn];
vector<int>g[maxn];
void dfs(int u,int isRed,int cnt,int fa,int cntt) {
vis[u]=1;
if(g[u].size()==1&&vis[g[u][0]]&&cntt<=m) {//判斷葉子節點的條件是這個點只有一個連接點,且那個連接點已被訪問過
ans++;
return;
}
for(int i=0; i<g[u].size(); i++) {
int v=g[u][i];
if(v==fa)continue;
if(red[v]==1) dfs(v,red[v],cnt+1,u,max(cntt,cnt+1));
else dfs(v,red[v],0,u,cntt);
}
return;
}
int main() {
cin>>n>>m;
for(int i=1; i<=n; i++)cin>>red[i];
for(int i=1; i<=n-1; i++) {
int x,y;
cin>>x>>y;
g[x].push_back(y);
g[y].push_back(x);
}
if(red[1]==1)dfs(1,red[1],1,-1,1);
else dfs(1,red[1],0,-1,0);
cout<<ans<<endl;
}