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 T, let F(T,i) F(T,i) be the distance between vertice 1 and vertice i i.(The length of each edge is 1).
Two trees A A and B B are similiar if and only if the have same number of vertices and for each i i meet F(A,i)=F(B,i) F(A,i)=F(B,i).
Two trees A A and B B are different if and only if they have different numbers of vertices or there exist an number i i which vertice i i have different fathers in tree A Aand tree B B when vertice 1 is root.
Tree A A is special if and only if there doesn't exist an tree B B which A A and B B are different and A A and B 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 T, let F(T,i) F(T,i) be the distance between vertice 1 and vertice i i.(The length of each edge is 1).
Two trees A A and B B are similiar if and only if the have same number of vertices and for each i i meet F(A,i)=F(B,i) F(A,i)=F(B,i).
Two trees A A and B B are different if and only if they have different numbers of vertices or there exist an number i i which vertice i i have different fathers in tree A Aand tree B B when vertice 1 is root.
Tree A A is special if and only if there doesn't exist an tree B B which A A and B B are different and A A and B B are similiar.
Now he wants to know if a tree is special.
It is too difficult for Rikka. Can you help her?
For each testcase, the first line contains a number n(1≤n≤1000) n(1≤n≤1000).
Then n−1 n−1 lines follow. Each line contains two numbers u,v(1≤u,v≤n) u,v(1≤u,v≤n) , which means there is an edge between u u and v v.
3
1 2
2 3
4
1 2
2 3
1 4
YES
NO
For the second testcase, this tree is similiar with the given tree: 4 1 2 1 4 3 4
中文题意:
问题描述众所周知,萌萌哒六花不擅长数学,所以勇太给了她一些数学问题做练习,其中有一道是这样的: 对于一棵树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
思路:根据题意总共只有三种情况:
所我们只需要用深搜一层一层进行搜索即可。然后记录每个节点的深度即可。
代码:
#include <cstdio> #include <cstring> #include <algorithm> #include <vector> using namespace std; int n; vector<int>g[1005]; vector<int>dis[1005]; bool vis[1005]; void dfs(int u, int d) { vis[u] = true; dis[d].push_back(u);//判断此点属于的层数 for (int i = 0; i < g[u].size(); i++) { int v = g[u][i]; if (!vis[v]) { //printf("##%d %d\n",v,d+1); dfs(v, d + 1);//向与之相连的点进行搜索 } } } int main() { while (~scanf("%d", &n)) { if (n == 1) { puts("YES"); continue; } for (int i = 0; i <= n; i++)g[i].clear(), dis[i].clear();//之前进行清空 memset(vis, false, sizeof vis); for (int i = 1; i < n; i++) { int u, v; scanf("%d %d", &u, &v); g[u].push_back(v);//表示:v属于u,目的用于统计属于u的点的集合 g[v].push_back(u);//u属于v } bool ans = true; dfs(1, 0); int t = 0; while ((int)dis[t].size() == 1)t++;//如果属于层数等于一的话的点数; int num = dis[t].size();//不等一的点数 if (num + t != n)ans = false;//相加等于n的话证明是特殊树,否则不是。 if (ans)puts("YES"); else puts("NO"); } return 0; }
用queue数组写:
#include<stdio.h> #include <iostream> #include<cstdio> #include<iostream> #include<algorithm> #include<math.h> #include<string.h> #include<map> #include<queue> #include<vector> #include<deque> #define ll long long #define inf 0x3f3f3f3f #define mem(a,b) memset(a,b,sizeof(a)) using namespace std; int vis[1001],n; vector<int> p[1001]; int dfs() { queue<int>q; q.push(1); vis[1]=1; int sum=1; while(!q.empty()) { int x=q.front(); q.pop();int temp=0; for(int i=0; i<p[x].size(); i++) { int y=p[x][i]; if(vis[y]==0) { vis[y]=1; q.push(y); temp++; } } sum+=temp; if(temp>1) { break; } } if(sum==n) return 1; else return 0; } int main() { //int n; while(~scanf("%d",&n)) { //mem(vis,0); int u,v;mem(vis,0); for(int i=0; i<=n; i++) { p[i].clear(); } for(int i=0; i<n-1; i++) { scanf("%d%d",&u,&v); p[u].push_back(v); p[v].push_back(u); } int ans=dfs(); if(ans==1) printf("YES\n"); else printf("NO\n"); } }