P11378 [GESP202412 七级] 燃烧

题目

传送门

思路

参考了洛谷的第一篇题解QWQ

如何求最大值?

遍历每个结点,以每个结点为根结点搜索比他小的儿子

如何在O(N)的时间复杂度下实现求点x能点燃的结点?

考虑记忆化搜索,前面找过的点就直接返回,否则就搜索比这个点小的结点

代码

有注释

#include<bits/stdc++.h>
using namespace std;
const int N=1e5+5; 
int n,ans=0;
int a[N]; 
int d[N];
vector<int>v[N];
int dfs(int x){
	if(d[x])return d[x];//前面找过了 
	int s=0;
	for(int i=0;i<v[x].size();i++){
		int u=v[x][i];
		if(a[u]<a[x]){//如果比他小 
			s+=dfs(u);
		}
	} 
	s++;//自己也要燃烧 
	d[x]=s;
	return d[x]; 
}
int main(){
	std::ios::sync_with_stdio(false);//关闭输入输出流 
	std::cin.tie(0);
	std::cout.tie(0);
	cin>>n;
	for(int i=1;i<=n;i++){
		cin>>a[i]; 
	} 
	for(int i=1;i<n;i++){
		int x,y;
		cin>>x>>y;
		v[x].push_back(y);
		v[y].push_back(x);
	}
	for(int i=1;i<=n;i++){
		ans=max(ans,dfs(i)); //以每个结点为根搜索 
	}
	cout<<ans;
	return 0;
} 

无注释

#include<bits/stdc++.h>
using namespace std;
const int N=1e5+5; 
int n,ans=0;
int a[N]; 
int d[N];
vector<int>v[N];
int dfs(int x){
	if(d[x])return d[x];
	int s=0;
	for(int i=0;i<v[x].size();i++){
		int u=v[x][i];
		if(a[u]<a[x]){
			s+=dfs(u);
		}
	} 
	s++;
	d[x]=s;
	return d[x];
}
int main(){
	std::ios::sync_with_stdio(false);
	std::cin.tie(0);
	std::cout.tie(0);
	cin>>n;
	for(int i=1;i<=n;i++){
		cin>>a[i]; 
	} 
	for(int i=1;i<n;i++){
		int x,y;
		cin>>x>>y;
		v[x].push_back(y);
		v[y].push_back(x);
	}
	for(int i=1;i<=n;i++){
		ans=max(ans,dfs(i)); 
	}
	cout<<ans;
	return 0;
} 

点赞QWQ

posted @ 2026-08-30 15:00  陈晨2011  阅读(4)  评论(0)    收藏  举报