求助:#6WA
查看原帖
求助:#6WA
149815
Isprime楼主2021/9/9 22:23

思路是求出树的直径的中点然后再选前 kk 个以这个节点为根的子树中节点的最大深度-这个点的深度最大的节点,在剩下的里面找最大的。

#6WA了,求神仙帮忙看看

#include <cstdio>
#include <algorithm>
using namespace std;
inline int read() {
	int res=0,f=1; char ch=getchar();
	while(ch<'0'||ch>'9') {if(ch=='-') f=-1; ch=getchar();}
	while(ch>='0'&&ch<='9') res=res*10+ch-'0',ch=getchar();
	return res*f;
}
const int MAXN=100005;
int n,k,ecnt;
int head[MAXN],dep[MAXN],mx[MAXN];
int fa[MAXN];
struct Edge {
	int next,to;
}e[MAXN<<1];
inline void add(int u,int v) {
	e[++ecnt].next=head[u];
	e[ecnt].to=v;
	head[u]=ecnt;
}
inline bool cmp(int a,int b) {return a>b;}
inline void dfs(int x,int u) {
	fa[x]=u;
	dep[x]=dep[u]+1;
	for(register int i=head[x];i;i=e[i].next) {
		int y=e[i].to;
		if(y==u) continue;
		dfs(y,x);
	}
}
inline void dfs2(int x,int u) {
	mx[x]=dep[x]=dep[u]+1;
	for(register int i=head[x];i;i=e[i].next) {
		int y=e[i].to;
		if(y==u) continue;
		dfs2(y,x);
		mx[x]=max(mx[x],mx[y]);
	}
}
signed main() {
	n=read(); k=read();
	for(register int u,v,i=1;i<n;++i) {
		u=read(); v=read();
		add(u,v); add(v,u);
	}
	dfs(1,1);
	int maxx=-1,s,t,num;
	for(register int i=1;i<=n;++i)
		if(dep[i]>maxx) maxx=dep[i],s=i;
	for(register int i=1;i<=n;++i)
		dep[i]=0;
	dfs(s,s);
	maxx=-1;
	for(register int i=1;i<=n;++i)
		if(dep[i]>maxx) maxx=dep[i],t=i;
	for(register int i=1;i<=dep[t]/2;++i)
		t=fa[t];
	for(register int i=1;i<=n;++i)
		dep[i]=0;
	dfs2(t,t);
	for(register int i=1;i<=n;++i)
		mx[i]=mx[i]-dep[i];
	sort(mx+1,mx+1+n,cmp);
	int ans=-1;
	for(register int i=k+1;i<=n;++i)
		ans=max(ans,mx[i]+1);
	printf("%d\n",ans);
    return 0;
}
2021/9/9 22:23
加载中...