《P5536 【XR-3】核心城市》

题目描述

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

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

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

输入格式

第一行 2 个正整数 n,k。

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

数据范围:

  • 1≤k<n≤105。
  • 1≤u,v≤n,u=v,保证城市与道路形成一棵树。

输出格式

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

输入输出样例

输入 #1复制

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

输出 #1复制

1

说明/提示

【样例说明】

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

代码实现:

#include<bits/stdc++.h>
#define loop(a, b, c) for(register int a = b; a <= c; a ++)
#define int64 long long
using namespace std;

inline int input(){
    int val = 0; bool sign = 1; char ch = getchar();
    for(; !isdigit(ch); ch = getchar())  if(ch == '-') sign = 0;
    for(; isdigit(ch); ch = getchar()) val = val * 10 + ch - '0';
    return sign ? val : -val;
}

queue <int> queue1, queue2; 
const int MAXN = 5e5 + 10;
int cityCount, coreCityCount, adjHead[MAXN], result;
struct Edge {
    int to, next;
} edges[MAXN];

int edgeCount = 0;
inline void addEdge(int from, int to) {
    edgeCount ++;
    edges[edgeCount].to = to;
    edges[edgeCount].next = adjHead[from];
    adjHead[from] = edgeCount;
}

int degree[MAXN];

int main(){
    cityCount = input(); coreCityCount = input();
    loop (i, 1, cityCount) adjHead[i] =-1;
    loop (i, 1, cityCount-1) {
        int u, v;
        u = input(); v = input();
        addEdge(u, v); addEdge(v, u);
        degree[u] ++; degree[v] ++;
    }
    int remainingCities = cityCount;
    loop (i, 1, cityCount) {
        if (degree[i] == 1) {
            queue1.push(i);
            degree[i] --;
        }
    }
    while(remainingCities > 0) {
        result ++;
        while (!queue1.empty()) {
            int currentCity = queue1.front();
            queue1.pop();
            remainingCities --;
            if (remainingCities == coreCityCount) {
                cout<<result<<endl;
                return 0;
            }
            for (int i = adjHead[currentCity]; i != -1; i = edges[i].next) {
                int neighborCity = edges[i].to;
                degree[neighborCity] --;
                if (degree[neighborCity] == 1) queue2.push(neighborCity);
            }
        }
        swap(queue1, queue2);
    }
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值