zoukankan      html  css  js  c++  java
  • 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 (≤10^4
    ) 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遍dfs,最后找到里面深度最深的那一些点,就好了。
    还有一种只需要两遍dfs就可以的,就是第一次从1号点dfs,然后从里面得到深度最深的点集s1,然后在从s1中任选一个点dfs,在得到深度最深的点集s2,答案是s1和s2的并集(这个方法要证明一下,有点类似树的直径那一题)。
    连通图用并查集判断。

    暴力代码

    #include<iostream>
    #include<cstring>
    #include<vector>
    
    using namespace std;
    
    const int N = 10010, M = 20010;
    
    int p[N];
    int n;
    int h[N], e[M], ne[M], idx;
    int w[N], vis[N], mx;
    
    int find(int x){
        if(x != p[x]) p[x] = find(p[x]);
        return p[x];
    }
    
    void add(int a, int b){
        e[idx] = b, ne[idx] = h[a], h[a] = idx ++;
    }
    
    void dfs(int u, int d){
        mx = max(mx, d);
        vis[u] = 1;
        for(int i = h[u]; i != -1; i = ne[i]){
            if(vis[e[i]] == 0) dfs(e[i], d + 1);
        }
    }
    
    int main(){
        memset(h, -1, sizeof h);
        
        cin >> n;
        
        for(int i = 1; i <= n; i ++) p[i] = i;
        
        for(int i = 1; i < n; i ++){
            int a, b;
            cin >> a >> b;
            add(a, b); add(b, a);
            if(find(a) != find(b)) p[find(b)] = p[find(a)];
        }
        
        int cnt = 0;
        for(int i = 1; i <= n; i ++) if(p[i] == i) cnt ++;
        if(cnt > 1){
            printf("Error: %d components", cnt);
            return 0;
        }
        
        for(int i = 1; i <= n; i ++){
            mx = 0;
            memset(vis, 0, sizeof vis);
            dfs(i, 0);
            w[i] = mx;
        }
        
        for(int i = 1; i <= n; i ++) mx = max(mx, w[i]);
        
        vector<int> res;
        
        for(int i = 1; i <= n; i ++)
            if(mx == w[i]) res.push_back(i);
            
        for(auto t : res) cout << t << endl;
        
        return 0;
    }
    

    两遍dfs代码

    #include<iostream>
    #include<cstring>
    #include<set>
    
    using namespace std;
    
    const int N = 100010, M = 200010;
    
    int p[N];
    int n;
    int h[N], e[M], ne[M], idx;
    int w[N], vis[N], mx;
    
    int find(int x){
        if(x != p[x]) p[x] = find(p[x]);
        return p[x];
    }
    
    void add(int a, int b){
        e[idx] = b, ne[idx] = h[a], h[a] = idx ++;
    }
    
    void dfs(int u, int d){
        w[u] = d;
        mx = max(mx, d);
        vis[u] = 1;
        for(int i = h[u]; i != -1; i = ne[i]){
            if(vis[e[i]] == 0) dfs(e[i], d + 1);
        }
    }
    
    int main(){
        memset(h, -1, sizeof h);
        
        cin >> n;
        
        for(int i = 1; i <= n; i ++) p[i] = i;
        
        for(int i = 1; i < n; i ++){
            int a, b;
            cin >> a >> b;
            add(a, b); add(b, a);
            if(find(a) != find(b)) p[find(b)] = p[find(a)];
        }
        
        int cnt = 0;
        for(int i = 1; i <= n; i ++) if(p[i] == i) cnt ++;
        if(cnt > 1){
            printf("Error: %d components", cnt);
            return 0;
        }
        
        dfs(1, 0);
        
        set<int> res;
        
        for(int i = 1; i <= n; i ++) 
            if(mx == w[i]) res.insert(i);
            
        mx = 0;
        memset(vis, 0, sizeof vis);
        dfs(*res.begin(), 0);
        
        for(int i = 1; i <= n; i ++)
            if(mx == w[i]) res.insert(i);
            
        for(auto t : res) cout << t << endl;
        
        return 0;
    }
    
  • 相关阅读:
    条件概率-独立事件-互斥事件-对立事件
    数学
    可视化:svg相关基础
    移动端调用摄像头(相机)相册
    移动端的事件点透及原因
    ios滑动流畅(丝般顺滑)滚动
    动画框架基础部分
    css美化select标签,兼容ie10 ie10+,chrome。但不支持ie9 ie9-
    ie11 调试工具不能使用
    css使用
  • 原文地址:https://www.cnblogs.com/tomori/p/13417792.html
Copyright © 2011-2022 走看看