Jeanny
寂兮,寥兮,独立不改,周行而不殆

 

P5536 【XR-3】核心城市

考察:树的中心 思维  码力

/*
P5536 【XR-3】核心城市
1.核心城市肯定包含中心,其他城市到达重心的距离就是最小值
2.如果k>中个数,k<=1e5
3.可以dfs延伸,以中心为根节点算层数,把一层多少个点算出来,sum[i]表示第i层有几个点
4.如果一旦k < sigma(sum[t]),最远的深度mxdep - t即为答案
5.手造数据,模拟
6.发现问题,如果这一层未满,最深的减t,之后呢
7.建立一个大根堆,每次-1,知道减完k-sigma,取堆顶
8.算复杂度nlogn
9.建立样例,写代码:
13 5
1 2
1 3
1 4
1 5
2 6
3 7
4 8
4 9
5 10
6 11
8 12
12 13
ans:2
*/

/*
错误:树的形态可能是两条链特别长,这样并不是以中心点一圈一圈的去建立核心城市
而是选择 mxd[u] - d[u]最长的k个点删除,mxd[]表示u这个点对应的叶子节点深度,
剩余mxd[u] - d[u]中最长的那个点+1即为答案
后半句一开始没想到,想了很久T_T
*/

#include<iostream>
#include<cstdio>
#include<map>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<queue>
#define ll long long
#define N 100005
using namespace std;
priority_queue<int> q;
int cnt, hd[N], rt, n, k, mx = 0x7fffffff, sum[N], g[N], x, y, d[N], mxd[N];
int dis[N];
struct Edge{
    int to, nxt;
}edge[N*2];
void add(int u, int v){
    cnt++;
    edge[cnt].to = v;
    edge[cnt].nxt = hd[u];
    hd[u] = cnt;
}
int pos1, pos2, mxdep = 0;
void dfs(int u, int fa, int dep){
    if(dep > mxdep){
        mxdep = dep; pos1 = u;
    }
    for(int i = hd[u]; i; i = edge[i].nxt){
        int v = edge[i].to;
        if(v == fa) continue;
        dfs(v, u, dep+1);
    }
}
void dfs1(int u, int fa, int dep){
    if(dep > mxdep){
        mxdep = dep; pos2 = u;
    }
    dis[u] = max(dis[u], dep);
    for(int i = hd[u]; i; i = edge[i].nxt){
        int v = edge[i].to;
        if(v == fa) continue;
        dfs1(v, u, dep+1);
    }
}

void work(int u, int fa, int dep){
    d[u] = mxd[u] = dep;
    // cout<<"d[u] "<<u<<" "<<d[u]<<endl;
    for(int i = hd[u]; i; i = edge[i].nxt){
        int v = edge[i].to;
        if(v == fa) continue;
        work(v, u, dep+1);
        mxd[u] = max(mxd[u], mxd[v]);
        // cout<<"ttt: "<<u<<" "<<mxd[v]<<endl;
    }
    // cout<<"q "<<u<<" "<<d[u]<<" "<<mxd[u]<<" "<<mxd[u]-d[u]<<endl;
    q.push(mxd[u] - d[u]);
}
int main(){
    scanf("%d%d",&n,&k);
    for(int i = 1; i <= n-1; i++){
        scanf("%d%d",&x,&y);
        add(x, y); add(y,x);
    }
    dfs(1, 0, 0);
    memset(dis, 0, sizeof dis); mxdep = 0; dfs1(pos1, 0, 0);
    dfs1(pos2, 0, 0);
    mx = 0x7fffffff;
    for(int i = 1; i <= n; i++){
        if(mx > dis[i]){
            mx = dis[i]; rt = i;
        }
    }
    // cout<<"rt: "<<rt<<endl;

    work(rt, 0, 0);
    // for(int i = 1; i <= n; i++){
    //     cout<<i<<" "<<d[i]<<" "<<mxd[i]<<endl;
    // }
    // cout<<"hhh "<<q.top()<<endl;
    for(int i = 1; i <= k; i++) q.pop();
    printf("%d\n", q.top() + 1);
    return 0;
}

 


 

posted on 2022-12-07 22:36  Jeanny  阅读(85)  评论(0)    收藏  举报