zoukankan      html  css  js  c++  java
  • luoguP5536 【XR-3】核心城市

    树的直径

    (dfs1)求直径的一端点

    (dfs2)求整个直径的长度,并保存下直径上的所有点

    然后(for)一边 (f) 数组(保存下来的点),求出中点

    (dfs3)(mid)为根来统计所有节点的深度,并算出每个节点能到达的最大深度

    然后求出相对深度,排序之后,前$ k$ 个 即满足题目要求,输出(k + 1) 就是答案

    因为在做差求相对深度的时候没有(+1) ,所以答案最后要$+1 $

    #include <bits/stdc++.h>
    using namespace std;
    const int N = 1e5 + 10;
    int e[N*2],ne[N*2],h[N],idx,f[N],d[N],mx,pos,mxd[N],dd[N];
    void add(int a,int b) {
        e[idx] = b;
        ne[idx] = h[a];
        h[a] = idx ++;
    }
    bool cmp(int a,int b) {
        return a > b;
    }
    void dfs1(int u,int fa) {// 求直径
        if(mx < d[u]) mx = d[u],pos = u;
        for(int i = h[u]; ~i; i = ne[i]) {
            int j = e[i];
            if(j == fa) continue;
            d[j] = d[u] + 1;
            dfs1(j,u);
        }
    }
    void dfs2(int u,int fa) {
        if(mx < d[u]) mx = d[u],pos = u;
        for(int i = h[u]; ~i;i = ne[i]) {
            int j = e[i];
            if(j == fa) continue;
            d[j] = d[u] + 1;
            f[j] = u;// 记录直径上的点
            dfs2(j,u);
        }
    }
    void dfs3(int u,int fa) {
        mxd[u] = d[u];
        for(int i = h[u]; ~i; i = ne[i]) {
            int j = e[i];
            if(j == fa) continue;
            d[j] = d[u] + 1;
            dfs3(j,u);
            mxd[u] = max(mxd[u],mxd[j]);
        }
    }
    
    int main() {
        int n,k;
        memset(h,-1,sizeof h);
        cin >> n >> k;
        for(int i = 0;i < n - 1; ++i) {
            int a,b;
            cin >> a >> b;
            add(a,b);
            add(b,a);
        }
        dfs1(1,0);
        memset(d,0,sizeof d);
        mx = 0;
        dfs2(pos,0);// 找直径
        int mid = pos;
        for(int i = 1;i <= (d[pos] + 1) / 2; ++i) mid = f[mid];
        memset(d,0,sizeof d);
        dfs3(mid,0);// 以中点为根,遍历树的深度,mxd[i] 代表i当前能走多深
        for(int i = 1;i <= n; ++i) dd[i] = mxd[i] - d[i];// 当前i能走多深 减去 当前的深度,就得到了绝对深度
        sort(dd + 1,dd + 1 + n,cmp);// 前 k 个城市联通 即可,第 k + 1即是答案
        cout << dd[k + 1] + 1;// mxd - d 是距离,但是没有加1,比如 1 到 5 的距离是  5 - 1 + 1,不是 5 - 1
        return 0;
    }
    
  • 相关阅读:
    Linux下数据库备份恢复过程
    BMC 安装操作系统以及 驱动的处理
    vCenter简单查看多少虚拟机在开机状态和一共多少虚拟机
    PDB自动启动以及Oracle Pfile的参数修改示范
    Oracle 测试环境 数据库安装过程
    CentOS Mininal 安装VMtools的方法
    日常工作 数据库中表与索引占用磁盘的简单分析
    Oracle数据库 查看表是否是 索引组织表的方法
    zabbix 使用问题两个--中文乱码,以及监控ESXi下的虚拟机
    Zabbix的简单使用
  • 原文地址:https://www.cnblogs.com/lukelmouse/p/13163411.html
Copyright © 2011-2022 走看看