zoukankan      html  css  js  c++  java
  • PAT 1021 Deepest Root

    #include <cstdio>
    #include <cstdlib>
    #include <vector>
    
    using namespace std;
    
    class Node {
    public:
        vector<int> adj;
        bool visited;
        Node() : visited(false) {}
    };
    
    void reset_nodes(vector<Node>& nodes) {
        int len = nodes.size();
        for (int i=0; i<len; i++) {
            nodes[i].visited = false;
        }
    }
    
    void dfs(int idx, vector<Node>& nodes, int level, int& deepest) {
        if (nodes[idx].visited) return;
        Node& node = nodes[idx];
        node.visited = true;
        if (level > deepest) deepest = level;
        
        int len = node.adj.size();
        for (int i=0; i<len; i++) {
            dfs(node.adj[i], nodes, level + 1, deepest);
        }
    }
    
    int find_deepest_from(int idx, vector<Node>& nodes) {
        int deepest = 0;
        // reset visited flag of all the nodes
        reset_nodes(nodes);
        
        // find the max level from this node(as root)
        dfs(idx, nodes, 0, deepest);
        
        int parts = 1;
        // check if other parts exist
        for (int i = nodes.size() - 1; i>=1; i--) {
            if (!nodes[i].visited) {
                int dummy = 0;
                dfs(i, nodes, 0, dummy);
                parts++;
            }
        }
        
        return parts > 1 ? -parts : deepest;
    }
    
    int main() {
        int N = 0;
        scanf("%d", &N);
    
        vector<Node> nodes(N + 1);
        
        for (int i=1; i<N; i++) {
            int a, b;
            scanf("%d%d", &a, &b);
            nodes[a].adj.push_back(b);
            nodes[b].adj.push_back(a);
        }
        
        int res = 0;
        vector<int> deepnodes;
        int deepest = 0;
        for (int i=1; i<=N; i++) {
            res = find_deepest_from(i, nodes);
            // not connected graph, stop search
            if (res < 0) {
                break;
            }
            if (res > deepest) {
                deepest = res;
                deepnodes.clear();
                deepnodes.push_back(i);
            } else if (res == deepest) {
                deepnodes.push_back(i);
            }
        }
        if (res < 0) {
            printf("Error: %d components
    ", -res);
        } else {
            int len = deepnodes.size();
            for (int i=0; i<len; i++) {
                printf("%d
    ", deepnodes[i]);
            }
        }
        return 0;
    }

    最深root的最远leaf也应该是最深root,利用这个做下优化的话速度应该会快不少。下午改写了一发,时间就有原来的1200ms降到了15ms,可见利用问题中的规律还是很有必要的:

    #include <cstdio>
    #include <cstdlib>
    #include <vector>
    #include <set>
    
    using namespace std;
    
    class Node {
    public:
        vector<int> adj;
        bool visited;
        Node() : visited(false) {}
    };
    
    void reset_nodes(vector<Node>& nodes) {
        int len = nodes.size();
        for (int i=0; i<len; i++) {
            nodes[i].visited = false;
        }
    }
    
    void dfs(int idx, vector<Node>& nodes, int level, int& deepest, set<int>& leaf) {
        if (nodes[idx].visited) return;
        Node& node = nodes[idx];
        node.visited = true;
        if (level > deepest) {
            deepest = level;
            leaf.clear();
            leaf.insert(idx);
        } else if (level == deepest) {
            leaf.insert(idx);
        }
        
        int len = node.adj.size();
        for (int i=0; i<len; i++) {
            dfs(node.adj[i], nodes, level + 1, deepest, leaf);
        }
    }
    
    int find_deepest_from(int idx, vector<Node>& nodes, set<int>& leaf) {
        int deepest = 0;
        // reset visited flag of all the nodes
        reset_nodes(nodes);
        
        // find the max level from this node(as root)
        dfs(idx, nodes, 0, deepest, leaf);
    
        int parts = 1;
        // check if other parts exist
        set<int> dummy_leaf;
        int dummy_deepest = 0;
        for (int i = nodes.size() - 1; i>=1; i--) {
            if (!nodes[i].visited) {
                dummy_leaf.clear();
                dummy_deepest = 100000;
                dfs(i, nodes, 0, dummy_deepest, dummy_leaf);
                parts++;
            }
        }
        if (parts > 1) return -parts;
        
        reset_nodes(nodes);
        vector<int> root(leaf.begin(), leaf.end());
        int len = root.size();
        
        for (int i=0; i<len; i++) {
            dfs(root[i], nodes, 0, deepest, leaf);
            leaf.insert(root[i]);
        }
        
        return parts > 1 ? -parts : deepest;
    }
    
    int main() {
        int N = 0;
        scanf("%d", &N);
    
        vector<Node> nodes(N + 1);
        
        for (int i=1; i<N; i++) {
            int a, b;
            scanf("%d%d", &a, &b);
            nodes[a].adj.push_back(b);
            nodes[b].adj.push_back(a);
        }
        
        int res = 0;
        set<int> deepnodes;
        int deepest = 0;
        res = find_deepest_from(1, nodes, deepnodes);
        // not connected graph
        if (res < 0) {
            printf("Error: %d components
    ", -res);
        } else {
            auto iter = deepnodes.begin();
            while (iter != deepnodes.end()) {
                printf("%d
    ", *iter++);
            }
        }
        return 0;
    }
  • 相关阅读:
    XAMPP 无法启动解决
    40 个轻量级 JavaScript 库 (上)
    WebService 异常处理方案
    datagridview
    生成噪点背景验证码代码
    checkbox的全选,反选
    listView绑定数据
    什么是工厂模式
    C#基础积累(二)面向对象
    后台使用类将对象序列化为JSon字符串
  • 原文地址:https://www.cnblogs.com/lailailai/p/4028220.html
Copyright © 2011-2022 走看看