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;
}