题意:
给你一棵
个节点的有根树,根节点为1,每个节点的权值为0或者1,问有多少条从根节点到叶子节点的路径,使得所经过的节点权值和不超过2 ?
解法一(深度优先搜索)
从根节点对整棵树进行dfs,然后计算答案
具体的:
我们定义递归函数
表示当前是以点
为根节点的子树,并且点
的父亲节点为
,当前经过的节点权值和为
,节点权值数组为
1. 将当前的
变量加上对应节点的权值,即
2. 若
大于2,则往下走到叶子结点一定不合法,故直接返回
3. 枚举当前节点
的所有儿子节点
(注意判断是否是父亲节点),然后往下递归,即)
4. 若当前节点没有儿子节点,则直接将答案+1
代码:
/**
* struct Point {
* int x;
* int y;
* Point(int xx, int yy) : x(xx), y(yy) {}
* };
*/
class Solution {
public:
int ans;//答案
vector<int> gr[100001];//邻接表存图
void dfs(int u,int fa,int cnt,vector<int>& f){
cnt+=f[u-1];//累加权值和
if(cnt>2)return;//若大于2,直接返回
bool flag=true;//标记当前节点是否有儿子节点
for(auto v:gr[u]){
if(v==fa)continue;
flag=false;
dfs(v,u,cnt,f);
}
if(flag)ans++;//当前节点是叶子节点
}
int solve(int n, vector<Point>& Edge, vector<int>& f) {
ans=0;
for(int i=1;i<=n;i++){
gr[i].clear();//多测清空
}
for(auto e:Edge){
//建双向边
gr[e.x].push_back(e.y);
gr[e.y].push_back(e.x);
}
dfs(1,0,0,f);
return ans;
}
}; 时间复杂度:空间复杂度:
解法二(广度优先搜索)
我们可以按照解法一按照层次遍历的顺序来计算答案
代码:
/**
* struct Point {
* int x;
* int y;
* Point(int xx, int yy) : x(xx), y(yy) {}
* };
*/
class Solution {
public:
vector<int> gr[100001];//邻接表存图
int father[100001];//父节点数组
struct node{//队列元素结构体
int p,cnt;//p为当前节点,cnt为当前节点权值和
inline node(int p,int cnt):p(p),cnt(cnt){}
};
int solve(int n, vector<Point>& Edge, vector<int>& f) {
for(int i=1;i<=n;i++){
gr[i].clear();//多测清空
}
for(auto e:Edge){
//连双向边
gr[e.x].push_back(e.y);
gr[e.y].push_back(e.x);
}
memset(father,0,sizeof father);//多测清空
queue<node> que;
que.push(node(1,f[0]));
int ans=0;
while(!que.empty()){
node t=que.front();//弹出队头
que.pop();
int u=t.p,cnt=t.cnt;
bool flag=true;//标记是否有儿子节点
for(auto v:gr[u]){
if(v==father[u])continue;
father[v]=u;//标记u的儿子节点的父亲节点为u
flag=false;
if(cnt+f[v-1]<=2){
que.push(node(v,cnt+f[v-1]));//塞入队列
}
}
if(flag)ans++;//是叶子节点,计算答案
}
return ans;
}
}; 时间复杂度: 空间复杂度:
,邻接表存图,
数组都是
大小的,故总的空间复杂度为

京公网安备 11010502036488号