【拓扑排序】洛谷 P5536 【XR-3】核心城市

【XR-3】核心城市

题目描述

X 国有 n 座城市,n1 条长度为 1 的道路,每条道路连接两座城市,且任意两座城市都能通过若干条道路相互到达,显然,城市和道路形成了一棵树。

X 国国王决定将 k 座城市钦定为 X 国的核心城市,这 k 座城市需满足以下两个条件:

  1. k 座城市可以通过道路,在不经过其他城市的情况下两两相互到达。
  2. 定义某个非核心城市与这 k 座核心城市的距离为,这座城市与 k 座核心城市的距离的最小值。那么所有非核心城市中,与核心城市的距离最大的城市,其与核心城市的距离最小。你需要求出这个最小值。

输入格式

第一行 2 个正整数 n,k

接下来 n1 行,每行 2 个正整数 u,v,表示第 u 座城市与第 v 座城市之间有一条长度为 1 的道路。

数据范围:

  • 1k<n105
  • 1u,vn,uv,保证城市与道路形成一棵树。

输出格式

一行一个整数,表示答案。

样例 #1

样例输入 #1

6 3
1 2
2 3
2 4
1 5
5 6

样例输出 #1

1

提示

【样例说明】

钦定 1,2,53 座城市为核心城市,这样 3,4,6 另外 3 座非核心城市与核心城市的距离均为 1,因此答案为 1


解析
思路参考:
https://www.luogu.com.cn/article/8zm2qhcz
拓扑排序扩展n-k个非核心城市,每次扩展距离1,当非核心城市的数量>n-k就break。此时扩展距离的最大值就是答案。

C++代码

#include <cstring>
#include <iostream>

using namespace std;

const int N = 1e5 + 10, M = N * 2;

int n, k, res;
int h[N], w[M], e[M], ne[M], idx;
int q[N], in[N], dist[N];

void add(int a, int b)
{
    e[idx] = b, ne[idx] = h[a], h[a] = idx++;
}

void topsort()
{
    int hh = 0, tt = -1;
    for (int i = 1; i <= n; i++)
        if (in[i] == 1) q[++tt] = i;

    while (hh <= tt)
    {
        int t = q[hh++];
        if (hh > n - k) break; // 非核心城市数超了n-k就停止
        for (int i = h[t]; i != -1; i = ne[i])
        {
            int j = e[i];
            dist[j] = dist[t] + 1;
            res = max(res, dist[j]);
            if (--in[j] == 1) q[++tt] = j;
        }
    }
}

int main()
{
    ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
    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);
        in[a]++, in[b]++;
    }
    topsort();
    cout << res;
    return 0;
}
posted @   Tshaxz  阅读(8)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 在鹅厂做java开发是什么体验
· 百万级群聊的设计实践
· WPF到Web的无缝过渡:英雄联盟客户端的OpenSilver迁移实战
· 永远不要相信用户的输入:从 SQL 注入攻防看输入验证的重要性
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
Language: HTML
点击右上角即可分享
微信分享提示