题目描述
珂朵莉给你一个有根树,求有多少个子树满足其内部节点编号在值域上连续
一些数在值域上连续的意思即其在值域上构成一个连续的区间
输入描述:
第一行有一个整数n,表示树的节点数。
接下来n–1行,每行两个整数x,y,表示存在一条从x到y的有向边。
输入保证是一棵有根树。
输出描述:
输出一个数表示答案
示例1
输入
5
2 3
2 1
2 4
4 5
输出
5
说明
节点1子树中编号为1,值域连续
节点3子树中编号为3,值域连续
节点5子树中编号为5,值域连续
节点4子树中编号为4,5,值域连续
节点2子树中编号为1,2,3,4,5,值域连续
备注:
对于100%的数据,有n <=100000
找到相应节点的最大最小值 和 节点总个数 xjb 搜一下 wa 了一次 数组开小了
#include<bits/stdc++.h>
using namespace std;
struct ac{
int mi,mx,sum;
ac(){
mi=999999;
mx=0;
sum=1;
}
}a[1000001];
int ans=0;
vector<int>q[100000];
void DFS(int x){
// cout<<"1"<<endl;
if(q[x].size()==0){
// a[x].sum=1;
a[x].mi=x;
a[x].mx=x;
ans++;
return ;
}
//cout<<q[x].size()<<endl;
for(int j=0;j<q[x].size();j++){
// cout<<q[x][j]<<endl;
DFS(q[x][j]);
a[x].sum+=a[q[x][j]].sum;
a[x].mx=max(a[x].mx,a[q[x][j]].mx);
a[x].mi=min(a[x].mi,a[q[x][j]].mi);
//cout<<a[q[x][j]].sum<<" "<<q[x][j]<<" "<<ans<<endl;
/* if(a[x].sum==a[x].mx-a[x].mi){
ans++;
//cout<<ans<<endl;
}*/
//cout<<a[q[x][j]].sum<<" "<<q[x][j]<<" "<<ans<<endl;
}
if(a[x].sum==a[x].mx-a[x].mi+1){
ans++;
//cout<<ans<<endl;
}
//cout<<a[x].mi<<" "<<a[x].mx<<" "<<a[x].sum<<endl;
}
int main(){
int n;
cin>>n;
int k=0;
for(int j=0;j<n-1;j++){
int x,y;
cin>>x>>y;
if(j==0) k=x;
q[x].push_back(y);
a[x].mi=x;
a[x].mx=x;
a[y].mi=y;
a[y].mx=y;
// cout<<q[x][0]<<endl;
}
// cout<<k<<endl;
DFS(k);
cout<<ans<<endl;
return 0;
}