时间限制: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; } }