• 九度 1536:树的最小高度


    题目描述:

    给定一棵无向树, 我们选择不同的节点作为根节点时,可以得到不同的高度(即树根节点到叶子节点距离的最大值), 现在求这棵树可能的最低高度。

    思路

    1. 刚开始题目都没看懂. 树的高度, 指的是根节点到叶节点的最大值, 我们要做的是找到最大值中的最小值

    2. 查了下资料, 发现这道题是裸求树的直径

    3. 树的直径可以用动规求解, 但基本的求法是用两次 BFS(DFS)

    4. BFS 的求解过程为, (1) 从任意节点 u 出发, 找到其能够达到的最远的节点 v (2) 再从 v 出发, 找到其能够达到的最远的节点 o (3) v,o 之间的距离就是树的直径 (4) 直径的一半就是所要求的高度

    证明 4 的正确性

    1. 假设 u 节点就在直径上. 假设 v 不在直径上, 那么必然有一点 v2 在直径上, 且 dis(u, v2) > dis(u,v), 这与 v 是 u 出发到达最远的点矛盾, 所以 v 在直径上(并且肯定在直径的一端)

    2. 假设 u 不在直径上, 那么 v 一定在直径上, 否则必然存在一个节点 v2 在直径上, 且 dis(u, v2) > dis(u,v)....

    3. 总之, v 一定在直径的一端, o 在另一端

    4. 关键点那题与这道类似

    代码

    用 dfs 做的, bfs 记录深度不太方便 

    #include <iostream>
    #include <stdio.h>
    #include <vector>
    #include <memory.h>
    #include <deque>
    using namespace std;
    
    vector<int> tree[1000010];
    bool visited[1000010];
    
    int depthIndex, maxDepth;
    void dfs(int n, int depth) {
        if(depth > maxDepth) {
            depthIndex = n;
            maxDepth = depth;
        }
    
        for(int i = 0; i < tree[n].size(); i ++) {
            int j = tree[n][i];
            if(visited[j]) continue;
            visited[j] = true;
            dfs(j, depth+1);
        }
    }
    int main() {
        //freopen("testcase.txt", "r", stdin);
        int n;
        while(scanf("%d", &n) != EOF) {
            if(n == 1) {
                cout << 0 << endl;
                continue;
            }else if(n == 2) {
                cout << 1 << endl;
                int a,b;
                scanf("%d%d", &a, &b);
                continue;
            }
    
            int a, b;
            for(int i = 0; i < n; i++)
                tree[i].clear();
    
            for(int i = 0; i < n-1; i ++) {
                scanf("%d%d", &a, &b);
                tree[a].push_back(b);
                tree[b].push_back(a);
            }
    
            maxDepth = 0;
            depthIndex = 0;
            memset(visited, 0, n+10);
            visited[0] = 1;
            dfs(0,0);
    
            memset(visited, 0, n+10);
            maxDepth = 0;
            visited[depthIndex] = 0;
            dfs(depthIndex, 0);
    
            int resVal = maxDepth-((maxDepth)>>1);
            printf("%d
    ", resVal);
        }
        return 0;
    }
  • 相关阅读:
    oracle常用的sql语句
    Tomcat内存调优
    基于Linux服务器的Oracle自动备份以及定时清除
    Windows 中Oracle数据库定时备份与清除
    CentOS 7 root密码修改
    weblogic忘记用户密码
    weblogic修改密码
    通过python自动获取小说并下载
    Linux修改本机名称
    CentOS无法正常启动
  • 原文地址:https://www.cnblogs.com/xinsheng/p/3579580.html
Copyright © 2020-2023  润新知