FZU 1227【鸡毛信问题】

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


树型动态规划。

学习中。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
const int MAX=50010;
using namespace std;
typedef struct nn
{
    int v;
    struct nn*next;
} node;
node set[2*MAX],*top,*adj[MAX];
int n,res[MAX],tmp[MAX];
inline node*create(int k,node*p)
{
    top->v=k;
    top->next=p;
    return top++;
}
bool input()
{
    int i,a,b;
    if(EOF==scanf("%d",&n))
    {
        return false;
    }
    memset(adj,0,n*sizeof(adj[0]));
    for(i=0,top=set; i<n-1; i++)
    {
        scanf("%d%d",&a,&b);
        adj[a]=create(b,adj[a]);
        adj[b]=create(a,adj[b]);
    }
    return true;
}
void edge(int v,int father)
{
    node*p,*pre;
    if(adj[v]->v==father)
    {
        adj[v]=adj[v]->next;
    }
    else
    {
        for(pre=adj[v],p=adj[v]->next; p; p=p->next,pre=pre->next)
        {
            if(p->v==father)
            {
                pre->next=p->next;
                break;
            }
        }

    }
    for(p=adj[v]; p; p=p->next)
    {
        edge(p->v,v);
    }
}

void solve(int v)
{
    node*p;
    int b,i,j;
    for(p=adj[v];p;p=p->next)
    {
        solve(p->v);
    }
    for(p=adj[v],b=0;p;p=p->next)
    {
        tmp[b++]=res[p->v];
    }
    sort(tmp,tmp+b);
    for(res[v]=0,i=b-1;i>=0;--i)
    {
        res[v]=max(res[v],tmp[i]+b-i);
    }
}
int main()
{
while(input())
{
    edge(0,-1);
    solve(0);
    printf("%d\n",res[0]);
}
    return 0;
}




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值