zoukankan      html  css  js  c++  java
  • 洛谷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;
    }
  • 相关阅读:
    VC常用代码
    richedit
    vc++ 2005 发布程序
    管道应用之捕获控制台程序信息
    黑客基础知识编程(转)
    Get All IE Info from win32 api
    vc 界面编程常用方法(http://blog.emuch.net/244485/spacelistblogitemtypeid2708.html)
    使用ADO调用存储过程
    在C#中如何实现文件夹的复制(转)
    C语言开发病毒程序(转)
  • 原文地址:https://www.cnblogs.com/landmine-sweeper/p/14102565.html
Copyright © 2011-2022 走看看