众所周知,萌萌哒六花不擅长数学,所以勇太给了她一些数学问题做练习,其中有一道是这样的: 对于一棵树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
对于第二组数据下面这棵树和它相似。 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; }