• $NOIP2018$赛道修建


    (NOIP2018)赛道修建

    树形结构不带树上算法走典型。

    (DFS),即可,考虑的方向不能脱离树状结构。

    即考虑一棵子树中分出的路线一定是独立的,而那些没用的边可以传上去作为备选答案。

    再考虑一个贪心,我们每次上传最大的即可。

    #include<bits/stdc++.h>
    using namespace std;
    namespace AE86
    {
    	const int bufl=1<<15;
    	char buf[bufl],*s=buf,*t=buf;
    	inline int fetch()
    	{
    		if(s==t){t=(s=buf)+fread(buf,1,bufl,stdin);if(s==t)return EOF;}
    		return*s++;
    	}
    	inline int read()
    	{
    		int a=0,b=1,c=fetch();
    		while(!isdigit(c)) b^=c=='-',c=fetch();
    		while(isdigit(c)) a=a*10+c-48,c=fetch();
    		return b?a:-a;
    	}
    }
    const int N=5e4+10;
    int n,m,num_edge,Sum,Ans;
    int head[N<<1],Dis[N];
    struct Edge{int next,to,dis;} edge[N<<1];
    inline void Add(int from,int to,int dis)
    {
    	edge[++num_edge].next=head[from];
    	edge[num_edge].dis=dis;
    	edge[num_edge].to=to;
    	head[from]=num_edge;
    }
    inline int Dfs(int pos,int fth,int k)
    {
    	multiset<int> S; S.clear();
    	for(int i=head[pos];i;i=edge[i].next)
    		if(edge[i].to!=fth)
    		{
    			int Bac=Dfs(edge[i].to,pos,k)+edge[i].dis;
    			if(Bac>=k) Ans++;
    			else S.insert(Bac);
    		}
    	int Max=0;
    	while(S.size())
    	{
    		if(S.size()==1) return max(Max,*S.begin());
    		multiset<int>::iterator It=S.lower_bound(k-*S.begin());
    		if(It==S.begin()&&S.count(*It)==1) It++;
    		if(It==S.end()) Max=max(Max,*S.begin()),S.erase(*S.begin());
    		else Ans++,S.erase(It),S.erase(S.begin());
    	}
    	return Max;
    }
    inline bool Check(int k)
    {
    	Ans=0; Dfs(1,0,k);
    	if(Ans>=m) return 1;
    	else return 0;
    }
    inline void Dfs_For_Dia(int pos,int fth)
    {
    	for(int i=head[pos];i;i=edge[i].next)
    		if(edge[i].to!=fth)
    		{
    			Dfs_For_Dia(edge[i].to,pos);
    			Sum=max(Sum,Dis[pos]+Dis[edge[i].to]+edge[i].dis);
    			Dis[pos]=max(Dis[pos],Dis[edge[i].to]+edge[i].dis);
    		}
    }
    int main(){
    #ifndef ONLINE_JUDGE
        freopen("A.in","r",stdin);
    #endif
    	n=AE86::read(),m=AE86::read();
    	for(int i=1,U,V,D;i<n;i++)
    		U=AE86::read(),V=AE86::read(),D=AE86::read(),Add(U,V,D),Add(V,U,D);
    	Dfs_For_Dia(1,0);int l=0,r=Sum;
    	while(l<r)
    	{
    		int mid=(l+r+1)>>1;
    		if(Check(mid)) l=mid;
    		else r=mid-1;
    	}
    	printf("%d
    ",l);
    }
    
  • 相关阅读:
    ETCD 添加节点报错 tocommit(2314438) is out of range [lastIndex(0)]. Was the raft log corrupted, truncated, or lost?
    如何删除docker镜像中已配置的volume
    kubeadm初始化集群
    kubeadm安装依赖镜像
    standard_init_linux.go:178: exec user process caused "no such file or directory"
    kubernetes支持local volume
    git http方式时保存密码
    分布式核心技术
    docker使用
    Python实用日期时间处理方法汇总
  • 原文地址:https://www.cnblogs.com/wo-shi-zhen-de-cai/p/11857841.html
Copyright © 2020-2023  润新知