zoukankan      html  css  js  c++  java
  • P3942 将军令

    Pro:https://www.luogu.com.cn/problem/P3942

    Sol:

    时隔多年重新学会了这道题目的正确做法

    首先我们可以得到这样一个显然的贪心就是
    每次找到一个深度最深的没被覆盖的点
    然后找到他的K级祖先
    然后把他K级祖先周围距离不超过K的点全部覆盖
    正确性显然
    但这样做的复杂度是和K有关系的

    考虑一个类似DP的方法
    对于每一个节点x
    去计算(f[x],g[x])两个数组
    F表示X的子树内没有被控制的最远点的距离
    G表示X的子树内已经选择的点最近点的距离
    考虑怎么递推

    [egin{align*} & F_x=max(F_{to})+1 \ & G_x=min(G_{to})+1 \ F_x+G_x<=k时:& F_x=-inf \ F_x==k时:& F_x=-inf,G_x=0,ans++ end{align*} ]

    再注意特判一下根节点的情况就可以了。。。。
    下面时写的很好的一篇题解
    (\\\)

    #include<bits/stdc++.h>
    #define N 550000
    #define eps 1e-7
    #define inf 1e9+7
    #define db double
    #define ll long long
    #define ldb long double
    #define ull unsigned long long
    using namespace std;
    inline int read()
    {
    	char ch=0;
    	int x=0,flag=1;
    	while(!isdigit(ch)){ch=getchar();if(ch=='-')flag=-1;}
    	while(isdigit(ch)){x=(x<<3)+(x<<1)+ch-'0',ch=getchar();}
    	return x*flag;
    }
    struct edge{int to,nxt;}e[N*2];
    int num,head[N];
    inline void add(int x,int y){e[++num]={y,head[x]};head[x]=num;}
    int n,k,ans,f[N],g[N];
    void dfs(int x,int fa)
    {
    	f[x]=0;g[x]=+inf;
    	for(int i=head[x];i!=-1;i=e[i].nxt)
    	{
    		int to=e[i].to;
    		if(to==fa)continue;
    		dfs(to,x);
    		f[x]=max(f[x],f[to]+1);
    		g[x]=min(g[x],g[to]+1);
    	}
    	if(f[x]+g[x]<=k)f[x]=-inf;
    	if((x==1&&f[x]>=0)||(f[x]==k))f[x]=-inf,g[x]=0,ans++;
    }
    int main()
    {
    	n=read();k=read();read();
    	num=-1;memset(head,-1,sizeof(head));
    	for(int i=1;i<n;i++){int x=read(),y=read();add(x,y);add(y,x);}
    	dfs(1,1);printf("%d",ans);
    	return 0;
    }
    
  • 相关阅读:
    Android开源框架——Volley
    Android中的事件传递机制
    @ViewDebug.ExportedProperty的使用
    字符间距——扩展
    读取assets文件夹下图片(ods_interview)
    Android消息推送——JPush极光推送
    深入模块
    正则表达式和re模块
    初识模块
    迭代器和生成器
  • 原文地址:https://www.cnblogs.com/Creed-qwq/p/13843406.html
Copyright © 2011-2022 走看看