列表

详情


JD20. 紧急疏散

描述

体育场突然着火了,现场需要紧急疏散,但是过道真的是太窄了,同时只能容许一个人通过。现在知道了体育场的所有座位分布,座位分布图是一棵树,已知每个座位上都坐了一个人,安全出口在树的根部,也就是1号结点的位置上。其他节点上的人每秒都能向树根部前进一个结点,但是除了安全出口以外,没有任何一个结点可以同时容纳两个及以上的人,这就需要一种策略,来使得人群尽快疏散,问在采取最优策略的情况下,体育场最快可以在多长时间内疏散完成。

数据范围:

输入描述

第一行包含一个正整数n,即树的结点数量。 接下来有n-1行,每行有两个正整数x,y,表示在x和y结点之间存在一条边。(1<=x,y<=n)

输出描述

输出仅包含一个正整数,表示所需要的最短时间

示例1

输入:

6
2 1
3 2
4 3
5 2
6 1

输出:

4

原站题解

C++ 解法, 执行用时: 24ms, 内存消耗: 2580KB, 提交时间: 2020-09-06

#include <vector>
#include <stdio.h>

using namespace std;
 // 使用并查集求出各个子树的最大节点数,即为最后结果
struct DSU {
    vector<int> f, cnt;
    DSU(int n) : f(n), cnt(n, 1) {
        for (int i = 0; i < n; i++)
            f[i] = i;
    }
 
    int find(int x) {
        if (f[x] == f[f[x]]) return f[x];
        return f[x] = find(f[x]);
    }
    bool merge(int x, int y) {
        int fx = find(x), fy = find(y);
        if (fx == fy) return false;
        f[fy] = fx;
        cnt[fx] += cnt[fy];
        return true;
    }
};
 
int main() {
    int n;
    scanf("%d", &n);
    DSU dsu(n+1);
 
    vector<int> root;
    for (int i = 1; i < n; i++) {
        int a, b;
        scanf("%d%d", &a, &b);
        if (a == 1) root.push_back(b);
        else if (b == 1) root.push_back(a);
        else dsu.merge(a, b);
    }
    int ans = 0;
    for (int a : root) ans = max(ans, dsu.cnt[dsu.find(a)]);
    printf("%d\n", ans);
    return 0;
 
}

C++ 解法, 执行用时: 25ms, 内存消耗: 1848KB, 提交时间: 2021-08-19

#include <vector>
#include <stdio.h>

using namespace std;
 // 使用并查集求出各个子树的最大节点数,即为最后结果
struct DSU {
    vector<int> f, cnt;
    DSU(int n) : f(n), cnt(n, 1) {
        for (int i = 0; i < n; i++)
            f[i] = i;
    }
 
    int find(int x) {
        if (f[x] == f[f[x]]) return f[x];
        return f[x] = find(f[x]);
    }
    bool merge(int x, int y) {
        int fx = find(x), fy = find(y);
        if (fx == fy) return false;
        f[fy] = fx;
        cnt[fx] += cnt[fy];
        return true;
    }
};
 
int main() {
    int n;
    scanf("%d", &n);
    DSU dsu(n+1);
    vector<int> root;
    for (int i = 1; i < n; i++) {
        int a, b;
        scanf("%d%d", &a, &b);
        if (a == 1) root.push_back(b);
        else if (b == 1) root.push_back(a);
        else dsu.merge(a, b);
    }
    int ans = 0;
    for (int a : root) ans = max(ans, dsu.cnt[dsu.find(a)]);
    printf("%d\n", ans);
    return 0;
 
}

上一题