ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

Luogu P5536

2021-04-12 19:01:24  阅读:195  来源: 互联网

标签:ch P5536 int Luogu 城市 register ret topo


听说 blog 食用更佳

核心思想 : topo


看了下好像题解都是写以直径为基础的算法,我来讲一下鄙人自己对于这道题的认识。

如图,这是一颗满足题目要求的无根树

这时,如果 \(k=2\) 那么显然 2 号城市和 4 号城市会成为核心城市,原因是此时所有非叶子节点都是非核心城市,答案为 1。

那么来看看下面这个图:

先设它的根为 1 号节点。

让我们看看 \(k=13\) 时是怎样的,很明显,所有的城市都可以成为核心城市,所以答案为0。

那当 \(k=7\) 时呢(有 6 个城市被排出在外时)?

你可以这样,此时答案是1且最优。

你也可以这样,此时答案是1且最优。

多画几个图,不难发现,当 \(5 \leq k \leq 12\) 时,答案都是1,此时所有非核心城市都有一个共同点:都是叶子节点(如下图)。

于是我们就可以想到由叶子节点一层层往内推统计城市个数,最后答案就是所有非核心城市的深度的最大值,这里的深度是由叶子节点为为第一层往根上推的,而根是什么根本无所谓。

是不是感觉和 topo 想法很像。


上代码!!!

# include <bits/stdc++.h>
using namespace std;

const int maxn = 100005;
const int maxe = 200005;

struct reader {
	template <typename Type>
	reader&operator>> (Type&ret) {
		register int f = 1; ret = 0; register char ch = getchar ();
		for (;!isdigit (ch); ch = getchar ()) if (ch=='-') f=-f;
		for (; isdigit (ch); ch = getchar ()) ret = (ret << 1) + (ret << 3) + ch - '0';
		ret *= f; return *this;
	}
}fin;// 快读

int N, K, x, y, du[maxn], ans;
int lnk[maxn], nxt[maxe], son[maxe], tot;
void add_e (register int x, register int y) {
	son[++tot] = y; nxt[tot] = lnk[x];
	lnk[x] = tot; du[y]++; return;
} // 邻接表存图
int que[maxn], dep[maxn], L, R; bool vis[maxn];
//这里的变量和数组都是字面意思,初中的教练一直要求代码要可以断章取义
void topo () {
	while (L ^ R) {
		L++;
		for (register int j = lnk[que[L]]; j; j = nxt[j]) {
			if (--du[son[j]] != 1) continue;
			//这一句不能落掉,是 topo 函数的关键
			if (vis[son[j]]) continue; vis[son[j]] = true;
			dep[son[j]] = dep[que[L]] + 1; ans = max (ans, dep[son[j]]);
			//这里随时刷新ans的最大值,可以防止后面再刷一遍
			que[++R] = son[j]; K--; if (K < 1) return;
		}
	}
	return;
} //其他的就是普通的 topo 写法了

int main () {
	freopen("P5536.in","r",stdin);
	freopen("P5536.out","w",stdout);
	fin >> N >> K; K = N - K; // 将 K 的含义转为非核心城市的个数
	for (register int i = 2; i <= N; i++) {
		fin >> x >> y;
		add_e (x, y); add_e (y, x);
	}	L = R = 0; ans = 0; // 建图
	for (register int i = 1; i <= N; i++) if (du[i] == 1 && K >= 1)
	que[++R] = i, vis[i] = true, K--, ans = 1, dep[i] = 1;
	//这一块原本是应该放在topo函数中的,但是因为加了个特判,所有写在主函数里
	if (K) topo (); cout << ans << endl;
	return 0;
}

最后,安利一波这个画图网站,真的超级好

Made By \(\operatorname{wheneveright}\)

标签:ch,P5536,int,Luogu,城市,register,ret,topo
来源: https://www.cnblogs.com/XJ21/p/14649517.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有