[Codeforces 980E] The Number Games

6 篇文章 0 订阅
1 篇文章 0 订阅

(emm…懒惰的博主终于开始写题解了,然而怎么还是水题。。)

传送门
题意:给出一颗 N N N个节点的树,第 i i i个节点的权值为 2 i 2^i 2i, 现在你必须删除 K K K个节点( K < N K < N K<N),并且保证剩下的点都联通的情况下,使得剩下的点权值最大。

删除 K K K个节点,就是选择 N − K N-K NK个节点嘛…
看到有 2 i 2^i 2i,应该很容易想到贪心的思路吧…
优先选取 i i i大的点,毕竟那些小的就算全部加起来也没这个大。。。
首先,节点 N N N肯定要选的啦,然后就以N为根了。
然后 i i i N − 1 N-1 N1枚举到1,因为题目要求联通,那从 i i i到根路径上所有未选点肯定都要选了,而且肯定是连续一条链。
那怎么找到这条链上离 i i i最远且未选过的点呢。。倍增就好了。。。
emm本来还想画个图…然而谁能给我推荐一下ubuntu下要用什么画啊。。。
而且博主是个连怎么装软件都没完全搞清楚的小白啊。。。。
扯…扯远了。。
贴代码吧

#include<bits/stdc++.h>
using namespace std;
const int N=1000001;
const int M=2000001;
const int Lg=20;
int n,m,Next[M],head[N],v[M],f[N][Lg],b[N],cnt,dep[N];   //b数组标记是否选过,f就是祖先的ST表

inline void read(int &x){
	char ch=getchar();x=0;
	for(;ch<'0'||ch>'9';ch=getchar());
	for(;ch>='0'&&ch<='9';ch=getchar()) x=(x<<3)+(x<<1)+ch-'0';
}

void add(int x,int y){   //挂链存边
	Next[++cnt]=head[x];
	head[x]=cnt;
	v[cnt]=y;
}

void dfs(int x,int fa){
	dep[x]=dep[fa]+1;
	f[x][0]=fa;
	for(int i=head[x];i!=-1;i=Next[i])
	 if (v[i]!=fa) dfs(v[i],x);
}

int getf(int x){   //找出这条链上离x最远且未选过的点
	for(int i=Lg-1;i>=0;i--)
	 if (!b[f[x][i]]) x=f[x][i];
	return f[x][0];
}

void baoli(int x){    //暴力将路径上的节点标记为选过
	for(;!b[x];x=f[x][0]) b[x]=1;
}

int main(){
	read(n);read(m);
	m=n-m;
	memset(head,-1,sizeof head);
	for(int i=1;i<n;i++){
		int x,y;
		read(x);read(y);
		add(x,y);
		add(y,x);
	}
	dfs(n,0);    //以n为根建树
	for(int i=1;i<Lg;i++)
	 for(int j=1;j<=n;j++)
	  f[j][i]=f[f[j][i-1]][i-1];   //建ST表用来倍增
	b[n]=1;b[0]=1;m--;
	for(int i=n-1;i;i--)
	 if (!b[i]){
		int fa=getf(i);
		if (dep[i]-dep[fa]<=m){
			m-=dep[i]-dep[fa];
			baoli(i);
		}
	 }
	for(int i=1;i<=n;i++)
	 if (!b[i]) printf("%d ",i);
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值