T1 A题
问题描述:
小A得到了一棵美丽的有根树。这棵树由n个节点以及n - 1条有向边构成,每条边都从父亲节点指向儿子节点,保证除了根节点以外的每个节点都有一个唯一的父亲。树上的节点从1到n标号。该树的一棵子树的定义为某个节点以及从该节点出发能够达到的所有节点的集合,显然这棵树共有n棵子树。小A认为一棵有根树是美丽的当且仅当这棵树内节点的标号构成了一个连续的整数区间。现在小A想知道这棵树上共有多少棵美丽的子树。
输入:
第一行有一个整数n,表示树的节点数。
接下来n–1行,每行两个整数u,v,表示存在一条从u到v的有向边。
输入保证该图是一棵有根树。
输出:
输出一个整数占一行,表示对应的答案。
样例输入:
4
2 3
2 1
2 4
样例输出:
3
数据范围:
对于20%的数据,1 ≤ n ≤ 1000。
对于100%的数据,1 ≤ n ≤ 100000。
一遍dfs,搜出一个节点的子树中权值最大最小的节点和这个节点的子节点有多少个,判断max-min==son-1就可以了。
代码
#include<queue>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
int head[100005],tov[100005],nex[100005],maxn[100005],minx[100005];
int ru[100005],way[100005],son[100005],ans,tot;
void add(int a,int b)
{
tov[++tot]=b;
nex[tot]=head[a];
head[a]=tot;
}
void dfs(int k)
{
int t=head[k];
int v=tov[t];
maxn[k]=minx[k]=k;
if(v==0)
{
ans++;
return ;
}
while(v)
{
dfs(v);
son[k]+=son[v]-1;
maxn[k]=max(maxn[k],maxn[v]);
minx[k]=min(minx[k],minx[v]);
t=nex[t];
v=tov[t];
}
if(maxn[k]-minx[k]==son[k]-1)
ans++;
}
int main()
{
freopen("A.in"