• 浙大pat甲级题目---1021. Deepest Root (25)


    A graph which is connected and acyclic can be considered a tree. The height of the tree depends on the selected root. Now you are supposed to find the root that results in a highest tree. Such a root is called the deepest root.

    Input Specification:

    Each input file contains one test case. For each case, the first line contains a positive integer N (<=10000) which is the number of nodes, and hence the nodes are numbered from 1 to N. Then N-1 lines follow, each describes an edge by given the two adjacent nodes' numbers.

    Output Specification:

    For each test case, print each of the deepest roots in a line. If such a root is not unique, print them in increasing order of their numbers. In case that the given graph is not a tree, print "Error: K components" where K is the number of connected components in the graph.

    Sample Input 1:

    5
    1 2
    1 3
    1 4
    2 5
    

    Sample Output 1:

    3
    4
    5
    

    Sample Input 2:

    5
    1 3
    1 4
    2 5
    3 4
    

    Sample Output 2:

    Error: 2 components
    

     题目大意:就是让比较一颗树的最大高度所对应的跟节点,如果有其他联通分支就输出联通分支数。

    题解:这道题由两部分,第一部分是求得图的联通分支数,如果大于一就输出个数。第二部分是如果联通分支数等于1就要寻找每一个顶点所对应的树高,并输出最大的树高所对应的节点。

    针对第一部分,我们使用并查集的概念去做(基本是固定套路),对于什么是并查集,并查集怎么用,我是参考的这篇博客,写的非常有意思,大家可以研究:

    http://blog.csdn.net/u013546077/article/details/64509038

    这里不做太多赘述。

    针对第二部分,这里选用dfs得到每个顶点的最短路径

    #include <iostream>
    #include<vector>
    #include<algorithm>
    #include<cstdio>
    #include<cstring>
    #define MAX 100001
    using namespace std;
    //并查集解决联通分之数的问题,dfs解决最高树问题
    int a[MAX];//并查集
    vector<int>graph[MAX];//学会用这种方式表达图的临街表
    vector<int>result;//存放最后输出结果的
    int visit[MAX];
    int length[MAX];//存放每个节点的最深长度
    void init(int n)//并查集初始化
    {
        for(int i=1;i<=n;i++)
        {
            a[i]=i;
        }
    }
    int find(int i)//查找i的根节点,且带路径压缩。目前看到最短版本
    {
        if(a[i]!=i)//当他的根不是自己(即还没找到根)
            a[i]=find(a[i]);//递归的寻找父亲
        return a[i];
    }
    void join(int i,int j)//节点i和j连接在一起
    {
        int x=find(i);
        int y=find(j);
        if(x!=y)
            a[x]=y;//联通两个分之
    }
    int dfs(int i)//以i为根,返回最大深度
    {
        int ans=0;
        int num=(int)graph[i].size();
        if(visit[i]==1)//叶子节点
            return 0;
        visit[i]=1;
        for(int j=0;j<num;j++)
        {
    
            int next=graph[i][j];
            if(visit[next]!=1)
            {
                 int deep=dfs(next);
                ans=max(deep,ans);
    
            }
        }
        return ans+1;
    }
    
    int main() {
        int n;
        int count=0;
        int max=-1;
        int index=0;
        scanf("%d",&n);
        init(n);
    
        for(int i=1;i<n;i++)//学会这种写临界表的方式
        {
            int x,y;
            scanf("%d%d",&x,&y);
            join(x,y);
            //将两者相连
            graph[x].push_back(y);
            graph[y].push_back(x);
        }
        for(int i=1;i<=n;i++)
        {
            if(a[i]==i)//当发现一个根的时候,联通分之数加一
                count++;
        }
        if(count!=1)
        {
            printf("Error: %d components
    ",count);
        }
        else
        {
            for(int i=1;i<=n;i++)
            {
                memset(visit,0, sizeof(visit));//注意每一次都要清空
                length[i]=dfs(i);
            }
            for(int i=1;i<=n;i++)//当题目中要求 输出很多相同大小的数的索引的时候,学会这种方法
            {
                if(length[i]>max)
                {
                    max=length[i];
                    index=i;
                }
            }
            for(int i=1;i<=n;i++)
            {
                if(length[i]==length[index])//很巧妙,相当于记下来最大的数,再循环
                    printf("%d
    ",i);
            }
    
        }
        return 0;
    }
  • 相关阅读:
    CentOS 设置mysql的远程访问
    centos的防火墙命令
    gorm的related理解和实例
    epoll相比select,poll的2个改进点
    limit越往后越慢,如何解决?
    LRUCache的设计,实现和调试
    map可以并发读,不能并发写
    2020年4月上旬算法讨论4(快排和堆排)
    删除链表节点代码编写复盘(从直接思路到优雅思路)
    2020年3月下寻算法讨论3(链表-下)
  • 原文地址:https://www.cnblogs.com/SK1997/p/8588527.html
Copyright © 2020-2023  润新知