【贪心】洛谷3942将军令

###贪心大法好
如果某个点没被控制,我们当然选择在他的第k的祖先哪里建站,这也就是贪心的思路。
这个“某个点”我们肯定要从深度最大的点开始。
所以说,先BFS一遍,BFS完的队列就是按深度从小到大排序的了,我们从最后开始往前面循环,
对于没有被控制的点,++ans,找出他的第k个祖先,然后dfs他的第k个祖先,向所有连接的点扩散,扩散深度为k,标记扩散到的点被控制。

然后就没有然后了。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <queue>
#include <set>
#include <map>
#include <vector>
#include <stack>
#include <list>
#define rep(i,m,n) for(int i=m;i<=n;i++)
#define dop(i,m,n) for(int i=m;i>=n;i--)
#define lowbit(x) (x&(-x))
#define ll long long
#define INF 2147483647
#define Open(s) freopen(s".in","r",stdin);freopen(s".out","w",stdout);
#define Close fclose(stdin);fclose(stdout);
using namespace std;

inline int read(){
    int s=0,w=1;
    char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-')w=-1;ch=getchar();}
    while(ch>='0'&&ch<='9') s=s*10+ch-'0',ch=getchar();
    return s*w;
}
inline void write(int x){
    if(x<0) x=-x,putchar('-');
    if(x>9) write(x/10);
    putchar(x%10+'0');
}
const int maxn = 100010 ;

int n , k , special , dis [ maxn ] , vis [ maxn ] , fa [ maxn ] , ans , que [ maxn ] ;

struct Edge {
	int next , to ;
} e [ maxn << 1 ] ;
int head [ maxn ] , num ;
void Add ( int from , int to ) {
	e [ ++num ] . to = to ;
	e [ num ] . next = head [ from ] ;
	head [ from ] = num ;
	swap ( from , to ) ;
	e [ ++num ] . to = to ;
	e [ num ] . next = head [ from ] ;
	head [ from ] = num ;
}

void bfs () {
	int head_ = 1 , tail = 1 ;
	fa [ 1 ] = 1 ; que [ tail++ ] = 1 ;
	while ( head_ < tail ) {
		int u = que [ head_++ ] ;
		for ( int i = head [ u ] ; i ; i = e [ i ] . next ) {
			if ( e [ i ] . to == fa [ u ] ) continue ;
			fa [ e [ i ] . to ] = u ; que [ tail++ ] = e [ i ] . to ;
		}
	}
}

void dfs ( int u , int dep ) {
	vis [ u ] = 1 ; dis [ u ] = dep ; 
	if ( ! dep ) return ;
	for ( int i = head [ u ] ; i ; i = e [ i ] . next ) 
		if ( dis [ e [ i ] . to ] < dis [ u ] - 1 || ! vis [ e [ i ] . to ] ) 
			dfs ( e [ i ] . to  , dep - 1 ) ;
}

int main () {
	n = read () ; k = read () ; special = read () ;
	rep ( i , 2 , n ) Add ( read () , read () ) ;
	bfs () ;
	dop ( i , n , 1 ) {
		int x = que [ i ] ;
		if ( ! vis [ x ] ) {
			++ans ;
			dop ( j , k , 1 ) x = fa [ x ] ;
			dis [ x ] = k ;
			dfs ( x , k ) ;
		}
	}
	write ( ans ) ;
	return 0 ;
}


  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值