C 游游的二进制树

题目描述

游游拿到了一棵树,共有nnn个节点,每个节点都有一个权值:0或者1。这样,每条路径就代表了一个二进制数。
游游想知道,有多少条路径代表的二进制数在[l,r][l,r][l,r]区间范围内?
(请注意:路径长度至少为1,例如,节点3到节点3虽然有一个权值,但并不是合法路径!)

输入描述:

第一行输入三个正整数n,l,r用空格隔开。
第二行输入一个长度为n的01串,第i个字符代表i号节点的权值。
接下来的n−1行,每行输入两个正整数u和v,代表u号节点和v号节点有一条边连接。
1≤n≤103
1≤u,v≤n
1≤l≤r≤1014

输出描述:


一个整数,代表合法的路径条数。

示例1

输入

4 4 5
1010
1 2
2 3
3 4

输出

3

说明


路径1-2-3代表的二进制数为5。

路径3-2-1代表的二进制数为5。

路径4-3-2-1代表的二进制数为5。

示例2

输入

3 1 2
100
1 2
1 3

输出

6

说明

任意合法路径均在区间[l,r]内。

代码实现

#include
using namespace std;
const int N=2e5+10;
vectorh[N];
string s;
long long n,l,r,ans;

void dfs(int u,int fa,long long mid){
	mid=mid*2+s[u-1]-'0';  //每次加上该点位的权值 
	if(mid>r)return;  //如果大于r则该路径不合法,退出递归 
	if(fa&&mid>=l)ans++;  //fa代表节点数 fa大于1代表最少2个节点 
	for(int v:h[u]){     //
		if(fa==v)continue;//不合法了,节点不会回头 
		dfs(v,u,mid);     //遍历以这一个节点的第一个值为节点的路径 
	}
}

int main(){
	cin>>n>>l>>r>>s;
	for(int i=1;i>x>>y;
		h[x].push_back(y);  //可以存储以一个数为起点,能达到的所有点 
		h[y].push_back(x);
	}
	for(int i=1;i<=n;i++)
	dfs(i,0,0);     //从第一个点开始查询,搜索所有以该点为起点的路径 
	cout<

你可能感兴趣的:(搜索每日一题,算法,深度优先)