• (树形dp)鸡毛信问题 (fzu 1227)


     

     Problem Description

    大革命时期,地下党组织的联络图是一个树状结构。每个党员只和一个比他高一级的负责人单线联系,但他可以与若干个比他低一级的直接下属党员联系。紧急情况通常用鸡毛信传递。假设容易复制鸡毛信,但传递1 次鸡毛信需要1 个单位时间。试设计一个算法,计算从总负责人开始,传递鸡毛信到每个党员手中最少需要多少时间。

    对于给定的地下党组织的联络图,计算从总负责人开始,传递鸡毛信到每个党员手中需的最少时间。

     Input

    第1行是党员总数n(1<n<50001)。全体党员编号为0,1,…,n-1。编号为0 的党员是总负责人。第2 行起共有n-1行,每行有2 个整数u 和v,表示党员u与党员v之间单线联系。

    处理到文件末尾。

     Output

    传递鸡毛信到每个党员手中需的最少时间。

     Sample Input

    4 0 2 0 3 1 2

     Sample Output

    2
     
    没写过树形dp的我想的太少了, 晉单纯的问为什么不用 BFS 来搜一下不就行了, 还用 dp 这种些法干嘛,陈学长说后, 感觉自己想法单纯到自己都觉得可笑
    举个例子, 很容易就能明白了  3 0 1 0 2 答案是 2,因为当 0 给 1 传的时候, 他就只能和 1 传, 因此和1,2就需要2个单位时间
     
     
    #include <stdio.h>
    #include <vector>
    #include <string.h>
    #include <algorithm>
    #include <iostream>
    #include <string>
    #include <limits.h>
    #include <stack>
    #include <queue>
    #include <set>
    #include <map>
    using namespace std;
    
    #define INF 0x3f3f3f3f
    #define met(a,b) (memset(a,b,sizeof(a)))
    const int N = 51000;
    
    struct node
    {
        int v, next;
    }a[N<<1];
    
    
    int Head[N], cnt, dp[N], vis[N];
    
    void Init()
    {
        cnt = 0;
        met(Head, -1);
        met(dp, -1);
        met(vis, 0);
    }
    
    void Add(int u, int v)
    {
        a[cnt].v = v;
        a[cnt].next = Head[u];
        Head[u] = cnt++;
    
        swap(u, v);
    
        a[cnt].v = v;
        a[cnt].next = Head[u];
        Head[u] = cnt++;
    }
    
    int DFS(int r)
    {
        vis[r] = 1;
        vector<int>Q;
    
        for(int i=Head[r]; i!=-1; i=a[i].next)
        {
             int v = a[i].v;
             if(vis[v]) continue;
             DFS(v);
             Q.push_back(dp[v]);
        }
    
        sort(Q.begin(), Q.end());
        int k=1, ans = Q.size();
        ///ans 记录的是与根节点 r 相连的点的个数
        ///之所以要sort,是因为当r有多个结点时,为了让花费的时间最小, 而排的
        for(int i=ans-1; i>=0; i--)
        {
            Q[i] += k;
            k++;
            dp[r] = max(Q[i], dp[r]);
        }
        if(ans==0)
            dp[r] = 0;
    }
    int main()
    {
        int n;
    
        while(scanf("%d", &n)!=EOF)
        {
            int i, u, v;
    
            Init();
            for(i=1; i<n; i++)
            {
                scanf("%d%d", &u, &v);
                Add(u, v);
            }
    
            DFS(0);
    
            printf("%d
    ", dp[0]);
        }
        return 0;
    }
  • 相关阅读:
    mysql5.7慢查询开启配置
    easyui的datagrid删除一条记录后更新出问题
    easyui跨iframe属性datagrid
    struts2笔记12-声明式异常
    struts2笔记11-OGNL
    struts2笔记10-值栈
    linux命令学习03-grep
    struts2笔记09-动态方法调用
    1、GIT简介
    玩转Python语言之4:奇技淫巧
  • 原文地址:https://www.cnblogs.com/YY56/p/5450440.html
Copyright © 2020-2023  润新知