zoukankan      html  css  js  c++  java
  • CF1039D You Are Given A Tree

    题目传送门:CF1039D

    洛谷入口

    题目大意:

    (给出一棵n个节点的树,对于的每一个数kin{[1,n]},你需要求出:)
    (最多能选出多少条互不相交的路径,每条路径的长度都为k)

    数据范围

    (circ) (nle10^5)

    题解

    这题的题意相信大家都能看懂
    对于一个数(kin{[1,n]})
    只看他,我们要思考一种方法去覆盖树
    其实如果去思考dfs时
    会发现对于一个点u
    只要u的众多子链(就是只由u的子节点们构成的一条链)
    其中最长的和次长的再加上u本身
    就能拼成可以DP不相互影响的一种路径
    如果这路径长度可以达到规定的k
    则可以把答案++,再把u记录的链长记为0表示已消耗
    这样就可以计算出对于一个k的答案
    好了完结了(没有)
    我们会出现一个问题,这样一遍dfs复杂度是(O(n))
    那么每一个要n,总共就要(O(n^2))了!
    (10^{10})——神仙也救不了
    所以要思考答案的特性
    我们都知道:k越大,答案不可能更大
    且会发现答案不同的最多只有(sqrt n)种(证明我也不好说明)
    所以可以去找一下答案相同的区间([l,r])再统一赋值
    这样可以去思考二分
    让mid的答案把可能性一个个限制住
    就渐渐达到了上述要求
    就没了!这题结束了!然后上代码↓↓↓

    AC代码

    //渐渐省略不必要的东西——头文件
    int tot,cnt,n,k,head[100010],dp[100010],d[100010];
    struct abc{
    	int to,nxt;
    }e[300010];
    //渐渐省略不必要的东西*2——链式前向星
    void dfs(int u,int fa,int ya){
    	int f=0,s=0;
    	d[u]=0;
    	for(int i=head[u];i;i=e[i].nxt){
    		int v=e[i].to;
    		if(v==fa)continue;
    		dfs(v,u,ya);
    		if(f<d[v])s=f,f=d[v];
    		else if(s<d[v])s=d[v];
    	}
    	if(f+s>=ya-1)tot++,d[u]=0;
    	else d[u]=f+1;
    }
    void dou(int l,int r,int zu,int yo){
    	if(l>r||zu>yo)return;
    	if(zu==yo){
    		for(int i=l;i<=r;i++)dp[i]=zu;
    		return;
    	}
    	int mid=l+r>>1;
    	tot=0;
    	dfs(1,0,mid);
    	dp[mid]=tot;
    	dou(l,mid-1,tot,yo);
    	dou(mid+1,r,zu,tot);
    }
    //渐渐省略一些不必要的东西*3——主函数
    

    支持一下吧,关注,点赞,评论都好!

    THE END

    Reality&Imagine
  • 相关阅读:
    请问set JAVA_OPTS的各项參数是什么意思?
    微软正式提供Visual Studio 2013正式版下载(附直接链接汇总)
    基础总结篇之中的一个:Activity生命周期
    [Cocos2d-x]Mac下cocos2d-x连接pomeloserver
    window.location.href的使用方法
    springMVC简单实例
    mybatis快速入门
    出现传值问题
    el表达式判断字符串相等
    EL表达式
  • 原文地址:https://www.cnblogs.com/yang-RA-NOI/p/12594662.html
Copyright © 2011-2022 走看看