zoukankan      html  css  js  c++  java
  • HDU 5423:Rikka with Tree Dijkstra算法

    Rikka with Tree

     
     Accepts: 207
     
     Submissions: 815
     Time Limit: 2000/1000 MS (Java/Others)
     
     Memory Limit: 65536/65536 K (Java/Others)
    问题描述
    众所周知,萌萌哒六花不擅长数学,所以勇太给了她一些数学问题做练习,其中有一道是这样的:
    
    对于一棵树TT,令F(T,i)F(T,i)为点1到点ii的最短距离(边长是1). 
    
    两棵树AABB是相似的当且仅当他们顶点数相同且对于任意的ii都有F(A,i)=F(B,i)F(A,i)=F(B,i).
    
    两棵树AABB是不同的当且仅当他们定点数不同或者存在一个ii使得以1号点为根的时候ii在两棵树中的父亲不同。
    
    一棵树AA是特殊的当且仅当不存在一棵和它不同的树和它相似。
    
    现在勇太想知道一棵树到底是不是特殊的。
    
    当然,这个问题对于萌萌哒六花来说实在是太难了,你可以帮帮她吗?
    输入描述
    数据组数不超过100组。每组数据的第一行一个整数n(2 leq n leq 1000)n(2n1000)。
    
    接下来n-1n1行。每行两个整数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 1 1 1 ... 1 1 x"。所以直接DFS一下求出每一个点到根的距离然后判断一下就好了 。

    看到从1到各个点的最短距离,就想到Dijkstra了。用Dijkstra求每个点的最短路径,之后在对最大值做判断即可。

    代码:

    #include <iostream>
    #include <algorithm>
    #include <cmath>
    #include <vector>
    #include <string>
    #include <cstring>
    #pragma warning(disable:4996)
    using namespace std;
    
    const int MAX = 0xfffffff;
    int edge[1005][1005];
    int vist[1005], minidis[1005];
    int num;
    
    void init()
    {
        int i, j;
        memset(vist, 0, sizeof(vist));
    
        for (i = 1; i <= num; i++)
        {
            for (j = 1; j <= num; j++)
            {
                if (j == i)
                    edge[i][j] = 0;
                else
                    edge[i][j] = -1;
            }
        }
        for (i = 1; i <= num; i++)
        {
            vist[i] = 0;
            minidis[i] = MAX;
        }
    }
    
    void dijkstra(int i)
    {
        int j, k;
        int position = i;
    
        vist[position] = 1;
        minidis[position] = 0;
    
        for (j = 1; j <= num - 1; j++)//一共要添加进num-1个点  
        {
            for (k = 1; k <= num; k++)
            {
                if (vist[k] == 0 && edge[position][k] != -1 && minidis[position] + edge[position][k] < minidis[k])//新填入的点更新minidis  
                {
                    minidis[k] = minidis[position] + edge[position][k];
                }
            }
            int min_value = MAX, min_pos;
            for (k = 1; k <= num; k++)
            {
                if (vist[k] == 0 && minidis[k]<min_value)//比较出最小的那一个作为新添入的店  
                {
                    min_value = minidis[k];
                    min_pos = k;
                }
            }
            vist[min_pos] = 1;
            position = min_pos;
        }
    
    }
    
    int main()
    {
        //freopen("i.txt", "r", stdin);
        //freopen("o.txt", "w", stdout);
    
        int i,j,temp1,temp2,max_v;
        while (scanf("%d", &num)!=EOF)
        {
            init();
            for (i = 1; i <= num - 1; i++)
            {
                scanf("%d%d", &temp1, &temp2);
                
                edge[temp1][temp2] = 1;
                edge[temp2][temp1] = 1;
            }
            dijkstra(1);
            bool flag = true;
    		max_v=-1;
    		for (i = 2; i <= num ; i++)
    		{
    			max_v=max(max_v,minidis[i]);
    		}
            for (i = 2; i <= num ; i++)
            {
                for (j = i + 1; j <= num; j++)
                {
                    if (minidis[i] == minidis[j]&&minidis[i] != max_v)
                        flag = false;
                }
            }
            if (flag)
                cout << "YES" << endl;
            else
                cout << "NO" << endl;
        }
        return 0;
    }


    版权声明:本文为博主原创文章,未经博主允许不得转载。

  • 相关阅读:
    鲲鹏服务器测试
    su与sudo的使用说明
    海天校园大型行业网站开发运营招募
    cat命令
    window与liunx下 nginx下载
    asp.net开发人员手册 昨天刚整理完
    centos nginx 安装文档 0.8.x
    高中物理公式、规律汇编表
    关于数据导入描述
    一键安装Nginx
  • 原文地址:https://www.cnblogs.com/lightspeedsmallson/p/4785761.html
Copyright © 2011-2022 走看看