HDU
来源:互联网 发布:淘宝达人收入很高 编辑:程序博客网 时间:2024/06/08 00:17
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 treeT 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 treesA 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 treesA 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.
TreeA 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
Two trees
Two trees
Tree
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
Then
31 22 341 22 31 4
YESNO
For the second testcase, this tree is similiar with the given tree:41 21 43 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"。
输入样例31 22 341 22 31 4
输出样例YESNO
Hint对于第二组数据下面这棵树和它相似。41 21 43 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"); }}
0 0
- hdu
- hdu
- HDU
- hdu ()
- hdu
- hdu
- HDU
- HDU
- hdu
- hdu
- HDU
- Hdu
- hdu
- hdu-
- hdu
- hdu
- hdu
- HDU
- (转载)数据库表分割技术浅析(水平分割/垂直分割/库表散列)
- 配置PL/SQL Developer 8
- (转载)正向代理与反向代理的区别
- js点击显示隐藏内容
- (转载)反向代理服务器的工作原理
- HDU
- main.jsp备份
- MyEclipse使用总结——使用MyEclipse打包带源码的jar包
- 扩容卡检测(win下,能作为参考)
- swustoj(0303取模)
- main.jsp修改后
- Snmp学习总结系列——开篇
- mxnet 在windows下安装
- 关于阅读EOC的一些笔记