zoukankan      html  css  js  c++  java
  • 1021. Deepest Root (25) -并查集判树 -BFS求深度

    题目如下:

    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
    

    这个题有N个顶点,N-1条边,属于稀疏图,应该用邻接矩阵而不是邻接表,否则会内存超限。

    刚开始拿到这道题目的时候我想到的方法是用带颜色标记的BFS判断环路,并且排除掉,但是这样会超时,后来在网上查阅,看到大家都是使用并查集来判断是否是树,通过把所有元素归入并查集,并且在查询根的时候压缩路径,如果所有元素都是同根的,那么把他们加入Set后集合的规模为1,说明是一棵完整的树,如果不是如此,则说明图由多个连通的部分组成,连通部分的个数等于根的个数,因此只需要输出Set的规模即可。

    如果是一棵树,只需要使用BFS来遍历树中的每一个顶点,来计算深度。

    为了计算深度,改进BFS,加入三个变量:head、last、tail,last表示这一层的最后一个元素,tail表示下一层的某个元素,初始化时,让last=s,代表第一层只有源点,接下来在出队一个结点,并让head等于这个结点,然后在遍历结点的邻接点时不断的更新tail,不难看出tail在最后一次更新后指向的是下一层的最后一个元素,然后判断head是否等于last,如果是代表本层结束,把层计数变量+1,更新last为tail,以此类推即可。

    #include <iostream>
    #include <stdio.h>
    #include <queue>
    #include <set>
    
    using namespace std;
    
    #define MAX 10002
    
    bool visited[MAX];
    vector<vector<int> > Graph;
    int N;
    int P[MAX];
    
    void initSet(int N){
    
        for(int i = 1; i <= N; i++) P[i] = i;
    
    }
    
    void CompressSet(int x, int top){
    
        if(P[x] != top){
            CompressSet(P[x],top);
            P[x] = top;
        }
    
    }
    
    int FindSet(int x){
    
        if(x != P[x]){
            int t = FindSet(P[x]);
            CompressSet(x,t);
        }
        return P[x];
    
    }
    
    void UnionSet(int x, int y){
    
        int p1 = FindSet(x);
        int p2 = FindSet(y);
        P[p1] = p2;
    
    }
    
    int BFS(int s){
    
        for(int i = 1; i <= N; i++) visited[i] = false;
        int head,tail,last;
        int stage = 0;
        queue<int> Q;
        Q.push(s);
        visited[s] = 1;
        last = s;
        while(!Q.empty()){
            int v = Q.front();
            visited[v] = 1;
            head = v;
            Q.pop();
            for(int index = 0; index < Graph[v].size(); index++){
                int w = Graph[v][index];
                if(!visited[w]){
                    Q.push(w);
                    tail = w;
                }
            }
            if(head == last){
                last = tail;
                stage++;
            }
    
        }
    
        return stage;
    
    }
    
    int main()
    {
        cin >> N;
        int v1,v2;
    
        Graph.resize(N + 1);
        initSet(N);
        for(int i = 1; i <= N; i++){
            visited[i] = false;
        }
    
        for(int i = 1; i < N; i++){
            scanf("%d%d",&v1,&v2);
            Graph[v1].push_back(v2);
            Graph[v2].push_back(v1);
        }
    
        for(int i = 1; i <= N; i++){
            for(int j = 0; j < Graph[i].size(); j++){
                UnionSet(i,Graph[i][j]);
            }
        }
    
        set<int> root;
        for(int i = 1; i<= N; i++){
            root.insert(FindSet(i));
        }
    
        if(root.size() != 1){
            printf("Error: %d components
    ",root.size());
            return 0;
        }
    
    
        vector<int> maxDeepNodes;
        maxDeepNodes.clear();
        int maxDepth = 0;
        int depth = 0;
    
        for(int i = 1; i <= N; i++){
            depth = BFS(i);
            if(depth > maxDepth){
                maxDepth = depth;
                maxDeepNodes.clear();
                maxDeepNodes.push_back(i);
            }else if(depth == maxDepth){
                maxDeepNodes.push_back(i);
            }
        }
    
        for(int i = 0; i < maxDeepNodes.size(); i++){
            printf("%d
    ",maxDeepNodes[i]);
        }
    
        return 0;
    }
    


  • 相关阅读:
    七层协议和四层协议
    eclipse 在jboss的debug配置(ubuntu系统)
    Maven三种仓库的配置
    oracle触发器使用
    为什么要进行URL编码
    LevelDB Compaction原理
    使用python处理selenium中的窗口切换问题
    使用python处理selenium中的鼠标悬停问题
    测试模型
    jenkins for mac
  • 原文地址:https://www.cnblogs.com/aiwz/p/6154169.html
Copyright © 2011-2022 走看看