时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 131072K,其他语言262144K
64bit IO Format: %lld
空间限制:C/C++ 131072K,其他语言262144K
64bit IO Format: %lld
题目描述
珂朵莉给你一个有根树,求有多少个子树满足其内部节点编号在值域上连续
一些数在值域上连续的意思即其在值域上构成一个连续的区间
输入描述:
第一行有一个整数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
找出每个子树的结点的个数,最大值和最小值,判断个数和最大值与最小值的差是否相等。
#include<map>
#include<queue>
#include<math.h>
#include<vector>
#include<string>
#include<stdio.h>
#include<iostream>
#include<string.h>
#include<algorithm>
#define inf 0x3f3f3f
#define ll long long
#define maxn 100005
using namespace std;
int vis[maxn];
int dis[maxn];
int a[maxn];
int mi[maxn],ma[maxn];
struct node
{
int v;
struct node *next;
}*h[maxn];
void LA(int u,int v)
{
struct node *p=(struct node*)malloc(sizeof(struct node));
p->v=v;
p->next=h[u];
h[u]=p;
}
void dfs(int x)
{
a[x]=1;
ma[x]=x;
mi[x]=x;
struct node *p;
if(h[x]==NULL)
return ;
for(p=h[x]; p!=NULL; p=p->next)
{
int u=p->v;
dfs(u);
a[x]+=a[u];
ma[x]=max(ma[x],ma[u]);
mi[x]=min(mi[x],mi[u]);
}
}
int main()
{
int t;
while(~scanf("%d",&t))
{
int n=t;
t--;
int m=0;
memset(vis,0,sizeof(vis));
memset(ma,0,sizeof(ma));
memset(mi,0,sizeof(mi));
for(int i=0; i<maxn; i++)h[i]=NULL;
while(t--)
{
int x,y;
scanf("%d%d",&x,&y);
LA(x,y);
vis[y]=1;
}
int ans=0;
for(int i=1; i<=n; i++)
{
if(vis[i]==0)
dfs(i);
}
for(int i=1; i<=n; i++)
{
if(a[i]==(ma[i]-mi[i]+1))
ans++;
}
cout<<ans<<endl;
}
}