问题描述
众所周知,萌萌哒六花不擅长数学,所以勇太给了她一些数学问题做练习,其中有一道是这样的: 对于一棵树TTT,令F(T,i)F(T,i)F(T,i)为点1到点iii的最短距离(边长是1). 两棵树AAA和BBB是相似的当且仅当他们顶点数相同且对于任意的iii都有F(A,i)=F(B,i)F(A,i)=F(B,i)F(A,i)=F(B,i). 两棵树AAA和BBB是不同的当且仅当他们定点数不同或者存在一个iii使得以1号点为根的时候iii在两棵树中的父亲不同。 一棵树AAA是特殊的当且仅当不存在一棵和它不同的树和它相似。 现在勇太想知道一棵树到底是不是特殊的。 当然,这个问题对于萌萌哒六花来说实在是太难了,你可以帮帮她吗?
输入描述
数据组数不超过100组。每组数据的第一行一个整数n(2≤n≤1000)n(2 \leq n \leq 1000)n(2≤n≤1000)。 接下来n−1n-1n−1行。每行两个整数u,v(1≤u,v≤n)u,v(1 \leq u,v \leq n)u,v(1≤u,v≤n),代表给定树上的一条边。
输出描述
对于每一组数据,如果给定树是特殊的输出"YES"否则输出"NO"。
输入样例
3 1 2 2 3 4 1 2 2 3 1 4
输出样例
YES NO
Hint
对于第二组数据下面这棵树和它相似。 4 1 2 1 4 3 4
容易发现一棵树是特殊的,当且仅当非叶子的结点个数不多于1个,那么DFS一遍求出每一层结点个数判断即可。
#include <stdio.h>
#include <string.h>
#include <algorithm>
using namespace std;
bool Map[1005][1005];
int d[1005],n,cnt[1005];
void dfs(int u,int dep)
{
d[u]=dep;
for(int i=1;i<=n;++i)
if(Map[u][i]&&d[i]==-1)
dfs(i,dep+1);
}
int main()
{
int x,y,i;
while(~scanf("%d",&n))
{
memset(Map,0,sizeof(Map));
for(i=0;i<n-1;++i){
scanf("%d%d",&x,&y);
Map[x][y]=Map[y][x]=1;
}
memset(d,-1,sizeof(d));
memset(cnt,0,sizeof(cnt));
dfs(1,0);
for(i=1;i<=n;++i)
cnt[d[i]]++;
int tmp=0;
for(i=1;i<n;++i)
{
if(cnt[i]){
if(cnt[i]<=cnt[tmp]&&cnt[tmp]>1) break;
else tmp=i;
}
}
if(i==n) puts("YES");
else puts("NO");
}
return 0;
}