hdu 5423 Rikka with Tree

问题描述
众所周知,萌萌哒六花不擅长数学,所以勇太给了她一些数学问题做练习,其中有一道是这样的:

对于一棵树TTT,令F(T,i)F(T,i)F(T,i)为点1到点iii的最短距离(边长是1). 

两棵树AAABBB是相似的当且仅当他们顶点数相同且对于任意的iii都有F(A,i)=F(B,i)F(A,i)=F(B,i)F(A,i)=F(B,i).

两棵树AAABBB是不同的当且仅当他们定点数不同或者存在一个iii使得以1号点为根的时候iii在两棵树中的父亲不同。

一棵树AAA是特殊的当且仅当不存在一棵和它不同的树和它相似。

现在勇太想知道一棵树到底是不是特殊的。

当然,这个问题对于萌萌哒六花来说实在是太难了,你可以帮帮她吗?
输入描述
数据组数不超过100组。每组数据的第一行一个整数n(2≤n≤1000)n(2 \leq n \leq 1000)n(2n1000)。

接下来n−1n-1n1行。每行两个整数u,v(1≤u,v≤n)u,v(1 \leq u,v \leq n)u,v(1u,vn),代表给定树上的一条边。
输出描述
对于每一组数据,如果给定树是特殊的输出"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;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值