美文网首页PAT甲级
1021 Deepest Root (25 分)

1021 Deepest Root (25 分)

作者: zju_dream | 来源:发表于2019-08-28 11:25 被阅读0次

    PAT原题

    ⚠️此题不能使用邻接矩阵,否则内存会超限,得使用邻接表。
    解决思路:

    • 连通分支+广度优先遍历
    • 首先广度优先搜索判断它有几个连通分量。如果有多个,那就输出Error: x components,如果只有一个,就两次广度优先搜索,先从一个结点bfs后保留最高高度拥有的结点们,然后从这些结点中的其中任意一个开始bfs得到最高高度的结点们,这两个结点集合的并集就是所求
    #include<iostream>
    #include<algorithm>
    #include<queue>
    #include<set>
    using namespace std;
    
    const int maxn = 10001;
    const int INF = 1000000000;
    int n;
    //bool G[maxn][maxn];
    vector<int> G[maxn];
    
    bool vis[maxn] = {false};
    struct Node
    {
        int idx;
        int layer;
    };
    
    bool cmp(int n1, int n2) {
        return n1 < n2;
    }
    
    int maxlayer = 1;
    vector<Node> allnodes;
    void bfs(int u) {
        allnodes.clear();
        fill(vis, vis+maxn, 0);
        maxlayer = 1;
        queue<Node> q;
        Node node;
        node.idx = u;
        node.layer = 1;
        q.push(node);
        allnodes.push_back(node);
        vis[u] = true;
    
        while(!q.empty()) {
            Node top = q.front();
            q.pop();
    
            for (int i = 0; i < G[top.idx].size(); ++i)
            {
                int v = G[top.idx][i];
                if(!vis[v]) {
                    Node temp;
                    temp.idx = v;
                    temp.layer = top.layer+1;
                    q.push(temp);
                    vis[temp.idx] = true;
                    allnodes.push_back(temp);
                    if(temp.layer > maxlayer) {
                        maxlayer = temp.layer;
                    }
                }
            }
        }
    }
    
    void simple_bfs(int u) {
        queue<int> q;
        q.push(u);
        vis[u] = true;
    
        while(!q.empty()) {
            int top = q.front();
            q.pop();
    
            for (int i = 0; i < G[top].size(); ++i)
            {
                int v = G[top][i];
                if(!vis[v]) {
                    q.push(v);
                    vis[v] = true;
                }
            }
        }
    }
    
    int main() {
        scanf("%d", &n);
        for (int i = 0; i < n-1; ++i)
        {
            int start, end;
            scanf("%d %d", &start, &end);
            G[start].push_back(end);
            G[end].push_back(start);
        }
    
        // 如果只含一个点
        if(n == 1) {
            printf("1\n");
            return 0;
        }
    
        // 这里还有问题,因为如果有环,不能检测出来, 但是恰好 边数=n-1,当只存在一个连通分支的时候,不可能会存在环。
        int cnt = 0;
        for (int i = 1; i <= n; ++i)
        {
            if(!vis[i]) {
                simple_bfs(i);
                cnt++;
            }
        }
        if(cnt > 1) {
            printf("Error: %d components\n", cnt);
            return 0;
        }
    
    
    
        int bestlayer=0;
        set<int> bestnodes;
        bfs(1);
        for (int i = allnodes.size()-1; i >= 0; --i)
        {
            if(allnodes[i].layer >= maxlayer) {
                bestnodes.insert(allnodes[i].idx);
            }
            else break;
        }
        bfs(*bestnodes.begin());
        for (int i = allnodes.size()-1; i >= 0; --i)
        {
            if(allnodes[i].layer >= maxlayer) {
                bestnodes.insert(allnodes[i].idx);
            }
            else break;
        }
    
        
        for (set<int>::iterator it = bestnodes.begin(); it != bestnodes.end(); it++)
        {
            printf("%d\n", *it);
        }
    
    }
    

    相关文章

      网友评论

        本文标题:1021 Deepest Root (25 分)

        本文链接:https://www.haomeiwen.com/subject/csdpectx.html