题目:https://codeforces.com/problemset/problem/580/C
#include<iostream>
#include<algorithm>
#include<vector>
#include<string>
#include<set>
using namespace std;
typedef long long ll;
const int maxn = 100000 + 10;
int res, m;
int arr[maxn];
bool vis[maxn];
struct Node
{
int from;
int next;
}edge[2*maxn];
int pre[maxn], in[maxn];//pre代表标号
void add(int index, int u, int v)
{
edge[index].from = v;//从v开始
edge[index].next = pre[u];
pre[u] = index;
}
void dfs(int v, int num)
{
if (num > m) { return; }//连续的顶点
if (in[v] == 1 && v != 1)res++;//说明能到达终点
if (vis[v]) { return; }
vis[v] = 1;
for (int i = pre[v]; i != -1; i = edge[i].next)
{
int t = edge[i].from;
if (arr[t] == 1)dfs(t, num + 1);
else { dfs(t, 0); }
}
}
int main()
{
int n;
while (~scanf("%d%d", &n, &m))
{
memset(pre, -1, sizeof(pre));
memset(vis, 0, sizeof(vis));
memset(in, 0, sizeof(in));
for (int i = 1; i <= n; i++)
{
scanf_s("%d", arr + i);
}
int index = 1;
for (int i = 0; i < n - 1; i++)
{
int u, v;
scanf_s("%d%d", &u, &v);//v是顶点 u是孩子
add(index, u, v);//建立双向边
index++;
add(index, v, u);
index++;
in[u]++, in[v]++;
}
res = 0;
dfs(1, arr[1]);
printf("%d\n", res);
}
}