您的位置:首页 > 其它

CF#321-C - Kefa and Park-DFS

2015-10-03 01:06 375 查看
http://codeforces.com/contest/580/problem/C

题意:

给n,m;

n个数构成一棵树

接下来n个数,表示每个点的权值(1,0) 1表示该节点有猫,0表示没

接下来n-1条边

 找出  有多少个     叶子节点,满足 叶子节点到根节点1的路径上 连续的 权值为1的点不超过 m个

直接dfs遍历邻接表,把节点的权值传递一遍

如果上一个点(累计连续权值)>m,  其下所有儿子都直接记为m+1

如果没,则上一个节点权值为1,【如果当前节点权值也为1,则当前累计权值为上次的+1,如果当前为0,当前累计权值更新为0】

   如果上一个节点权值为0 ,【当前节点累计权值与 自己的权值一样】

#include <cstdio>
#include <cmath>
#include <cstring>
#include <string>
#include <algorithm>
#include <iostream>
#include <queue>
#include <set>
#include <vector>
using namespace std;

int cat[100005];
int du[100005];
int tm[100005];
vector <int> map[100005];
int vis[100005];
int m;
int main()
{
void dfs(int j);
int n,i;
scanf("%d%d",&n,&m);
int a,b;
for (i=1;i<=n;i++)
{
scanf("%d",&tm[i]);
}

for (i=1;i<=n-1;i++)
{
scanf("%d%d",&a,&b);
du[a]++;
du[b]++;
map[a].push_back(b);
map[b].push_back(a);
}

cat[1]=tm[1];
vis[1]=1;
dfs(1);

int cun=0;
for (i=2;i<=n;i++) //注意i=1不能算是答案
{
if (du[i]==1&&cat[i]<=m)
cun++;
}

printf("%d\n",cun);
return 0;

}

void dfs(int j)
{
int i;
for (i=0;i<map[j].size();i++)
{

int t=map[j][i];
if (vis[t]) //标记已经访问过
continue;
if (cat[j]>m) //如果有一个点处已经超m,那么往下所有点都不合法
{
cat[t]=m+1;
}
else
{

if (tm[j]==1)
{
if (tm[t]==1)
cat[t]=cat[j]+1;
else
cat[t]=0;
}
else
cat[t]=tm[t];
}
vis[t]=1;
dfs(t);
}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: