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; }