• 洛谷P2018 消息传递


    题目

    https://www.luogu.com.cn/problem/P2018

    思路

    由题意得这是一棵树,而任何一个已经接到消息的人,都可以把消息告诉他的一个直接上级或者直接下属,说明是一棵无根树。

    本来以为要用什么高端树上算法乱搞,结果发现(Nleq 1000),这不是dfs就能水过吗?(实际上是个树规)

    钦定一个结点为根,我们在有根树上做树规。对于结点(x),他的状态由他的子结点决定。简单思考一下可以发现,最优决策一定是先告诉耗时长的子结点。转移方程不太好写,直接看代码吧。

    int dfs(int x){
        int i,num=0,tmp[1010];
        book[x]=1;
        for(i=fst[x];i;i=nxt[i]){
            if(book[to[i]]) continue;
            tmp[++num]=dfs(to[i]);
        }
        sort(tmp+1,tmp+num+1);
        for(i=1;i<=num;i++){
            dp[x]=max(dp[x],tmp[i]+num+1-i);
        }
        return dp[x];
    }
    

    这就是最核心的部分。

    做了(n)次dfs,而每一次的复杂度最坏是(nlogn),总时间复杂度(n^2logn),完全没有问题。

    代码

    #include<cstdlib>
    #include<queue>
    #include<cstring>
    #include<algorithm>
    #define inf 0x3f3f3f3f
    #define maxn 1010
    using namespace std;
    int to[maxn<<1],fst[maxn],nxt[maxn<<1],cnt=0,t[maxn],dp[maxn],book[maxn];
    void add(int x,int y){
        to[++cnt]=y;
        nxt[cnt]=fst[x];
        fst[x]=cnt;
    }
    int dfs(int x){
        int i,num=0,tmp[1010];
        book[x]=1;
        for(i=fst[x];i;i=nxt[i]){
            if(book[to[i]]) continue;
            tmp[++num]=dfs(to[i]);
        }
        sort(tmp+1,tmp+num+1);
        for(i=1;i<=num;i++){
            dp[x]=max(dp[x],tmp[i]+num+1-i);
        }
        return dp[x];
    }
    int main(){
        int i,j,n,m,x,ans=inf;
        scanf("%d",&n);
        for(i=2;i<=n;i++){
            scanf("%d",&x);
            add(i,x);add(x,i);
        }
        for(i=1;i<=n;i++){
            memset(dp,0,sizeof(dp));
            memset(book,0,sizeof(book));
            t[i]=1+dfs(i);
            ans=min(ans,t[i]);
        }
        printf("%d
    ",ans);
        for(i=1;i<=n;i++)
            if(t[i]==ans) printf("%d ",i);
        system("pause");
        return 0;
    }
  • 相关阅读:
    Ubuntu 16.04远程登录服务器--ssh的安装和配置
    设置淘宝源
    shell 循环 read line
    apt-get update 报错 W: Unknown Multi-Arch type 'no' for package 'compiz-core'
    expdp dblink
    ubuntu apt-update NO_PUBKEY 40976EAF437D05B5 NO_PUBKEY 3B4FE6ACC0B21F32
    listener.log文件过大导致oracle假死
    rsync_ssh
    ssh多主机
    elk大纲
  • 原文地址:https://www.cnblogs.com/landmine-sweeper/p/14102565.html
Copyright © 2020-2023  润新知