Rikka with Tree
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)
Problem Description
As we know, Rikka is poor at math. Yuta is worrying about this situation, so he gives Rikka some math tasks to practice. There is one of them:
For a tree T , let F(T,i) be the distance between vertice 1 and vertice i .(The length of each edge is 1).
Two trees A and B are similiar if and only if the have same number of vertices and for each i meet F(A,i)=F(B,i) .
Two trees A and B are different if and only if they have different numbers of vertices or there exist an number i which vertice i have different fathers in tree A and tree B when vertice 1 is root.
Tree A is special if and only if there doesn't exist an tree B which A and B are different and A and B are similiar.
Now he wants to know if a tree is special.
It is too difficult for Rikka. Can you help her?
For a tree T , let F(T,i) be the distance between vertice 1 and vertice i .(The length of each edge is 1).
Two trees A and B are similiar if and only if the have same number of vertices and for each i meet F(A,i)=F(B,i) .
Two trees A and B are different if and only if they have different numbers of vertices or there exist an number i which vertice i have different fathers in tree A and tree B when vertice 1 is root.
Tree A is special if and only if there doesn't exist an tree B which A and B are different and A and B are similiar.
Now he wants to know if a tree is special.
It is too difficult for Rikka. Can you help her?
Input
There are no more than 100 testcases.
For each testcase, the first line contains a number n(1≤n≤1000) .
Then n−1 lines follow. Each line contains two numbers u,v(1≤u,v≤n) , which means there is an edge between u and v .
For each testcase, the first line contains a number n(1≤n≤1000) .
Then n−1 lines follow. Each line contains two numbers u,v(1≤u,v≤n) , which means there is an edge between u and v .
Output
For each testcase, if the tree is special print "YES" , otherwise print "NO".
Sample Input
3 1 2 2 3 4 1 2 2 3 1 4
Sample Output
YES NOHintFor the second testcase, this tree is similiar with the given tree: 4 1 2 1 4 3 4
Source
/************************************************************************/
附上该题对应的中文题
Rikka with Tree
Accepts: 173
Submissions: 353
Time Limit: 2000/1000 MS (Java/Others)
Memory Limit: 65536/65536 K (Java/Others)
问题描述
众所周知,萌萌哒六花不擅长数学,所以勇太给了她一些数学问题做练习,其中有一道是这样的: 对于一棵树T,令F(T,i)为点1到点i的最短距离(边长是1). 两棵树A和B是相似的当且仅当他们顶点数相同且对于任意的i都有F(A,i)=F(B,i). 两棵树A和B是不同的当且仅当他们定点数不同或者存在一个i使得以1号点为根的时候i在两棵树中的父亲不同。 一棵树A是特殊的当且仅当不存在一棵和它不同的树和它相似。 现在勇太想知道一棵树到底是不是特殊的。 当然,这个问题对于萌萌哒六花来说实在是太难了,你可以帮帮她吗?
输入描述
数据组数不超过100组。每组数据的第一行一个整数n(2≤n≤1000)。 接下来n−1行。每行两个整数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
/****************************************************/
出题人的解题思路:
Rikka with Tree
显然一棵树是独特的当且仅当任意处于每一个深度的点数是"1 1 1 1 ... 1 1 x"。所以直接DFS一下求出每一个点到根的距离然后判断一下就好了 。
对于此题,就是让我们判断给定的树是不是特殊的树,根据题目的定义,一棵树A是特殊的当且仅当不存在一棵和它不同的树和它相似,简而言之,就是对于给定的树,不存在那么一棵树,满足[结点数相同,F(A,i)=F(B,i),且以1号点为根的时候i在两棵树中的父亲不同 ]
其实,仔细思考一下,就会发现,这样的树只有一种可能性,即如下图所示
像这种中间层(除根与叶子层)结点超过1个的树,都不是特殊的树,因为只要变换其叶子结点的位置,就能找到一个满足[结点数相同,F(A,i)=F(B,i),且以1号点为根的时候i在两棵树中的父亲不同]的树
所以,我们只需用bfs或dfs判断除叶子层外是不是每一层都只有一个结点即可
#pragma comment(linker, "/STACK:1024000000,1024000000")
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<queue>
#include<stack>
#include<math.h>
#include<vector>
#include<map>
#include<set>
#include<stdlib.h>
#include<cmath>
#include<string>
#include<algorithm>
#include<iostream>
#define exp 1e-10
using namespace std;
const int N = 1001;
const int inf = 1000000000;
const int mod = 2009;
vector<int> s[N];
int ans[N],v[N];
void bfs(int n)
{
queue<int> q;
q.push(n);
v[n]=1;
while(!q.empty())
{
int t=q.front();
q.pop();
for(int i=0;i<s[t].size();i++)
if(!v[s[t][i]])
{
q.push(s[t][i]);
v[s[t][i]]=v[t]+1;
}
}
}
int main()
{
int n,i,a,b,Max;
while(~scanf("%d",&n))
{
memset(ans,0,sizeof(ans));
memset(v,0,sizeof(v));
for(i=1;i<=n;i++)
s[i].clear();
for(i=1;i<n;i++)
{
scanf("%d%d",&a,&b);
s[a].push_back(b);
s[b].push_back(a);
}
bfs(1);
for(Max=0,i=1;i<=n;i++)
{
ans[v[i]]++;
Max=max(Max,v[i]);
}
for(i=1;i<Max;i++)
{
//printf("%d\n",ans[i]);
if(ans[i]!=1)
break;
}
if(i!=Max)
puts("NO");
else
puts("YES");
}
return 0;
}
菜鸟成长记