【dfs】树(jzoj 2753)

jzoj 2753

题目大意:

给你一棵树,每一个点都一个值,现在问你有多少条路径可以满足以下条件:
1、方向都是向下
2、路径上的点的值总和为S

输入样例

3 3
1 2 3
1 2
1 3

输出样例

2

数据范围

对于30%数据, N 100 N \leqslant 100
对于60%数据, N 1000 N \leqslant 1000
对于100%数据, N 100000 N \leqslant 100000 ,所有权值以及S都不超过1000。

解题思路:

从根节点开始搜索,用一个值num来记录根节点到当前点的值总和
如果以某一个点为路径开始,拿如果下面有某一个点的num为当前点的num加S那这就是一条合法路径

代码:

#include<map> 
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define ll long long
using namespace std;
int n, s, x, y, ans, tot, b[105000], head[105000];
map< int , int >p;
struct rec
{
	int to, next;
}a[105000];
void add(int x, int y)
{
	a[++tot].to = y;
	a[tot].next = head[x];
	head[x] = tot;
}
void dfs(int x, int num)
{
	int k = p[num + s];//记录num为这个值的点有多少个
	p[num + b[x]]++;//多了一个
	for (int i = head[x]; i; i = a[i].next)
		dfs(a[i].to, num + b[x]);//搜索
	ans += p[num + s] - k;//看多了多少
}
int main()
{
	scanf("%d%d", &n, &s);
	for (int i = 1; i <= n; ++i)
		scanf("%d", &b[i]);
	for (int i = 1; i < n; ++i)
	{
		scanf("%d%d", &x, &y);
		add(x, y);//连边
	}
	dfs(1, 0);
	printf("%d", ans);
	return 0;
}
发布了334 篇原创文章 · 获赞 57 · 访问量 3万+

猜你喜欢

转载自blog.csdn.net/ssllyf/article/details/104267987
今日推荐