文章详情

  • 游戏榜单
  • 软件榜单
关闭导航
热搜榜
热门下载
热门标签
php爱好者> php文档>[吼吼]加工树枝

[吼吼]加工树枝

时间:2010-09-23  来源:雲中君

【描述】

Dragon同学一天捡到了一根非常非常巨大的树枝,于是同学就想啊,如果把这根树枝多余的分叉剔掉最后剩下一根没有分叉的木棍,用它自卫就没人敢欺负我们科学家了呀:)

你的任务是,对给定树枝,求出它包含的最长木棍。

【输入格式】

第一行一个正整数n,表示顶点数,顶点从1至n编号。

然后n – 1行每行两个正整数u, v表示u, v之间有一条边,每条边的长度为1。

保证输入的是一棵树。

【输出格式】

只有一行,表示给定树的最长链长度。

【样例输入】

5

1 2

1 3

1 4

1 5

【样例输出】

2

【分析】

很明显,求树中的最长链。设f[i]是i的子树中最远的点到自己的距离,p[i]是第二远的点到自己的距离。那么所有的点钟最大的f[i]+p[i]就是答案。

第一次写——临边表。显然存不下。

第二次写——模拟链表。用的递归造树,爆掉。

想到了要用手工的栈。

可是我不知道怎么写囧。

于是看了标程。

原来还可以这么构树!!!

原来手工栈这么写!!!

顿悟。

第三次——AC。

#include <stdio.h>
#include <stdlib.h>
#define maxn 1000010

int f[maxn];
int father[maxn],str[maxn];
struct ss
{
       int num,next;
} a[maxn];
int tot,n,u,v,p,ans;
int c[maxn],deep[maxn],sta[maxn],top,e[maxn],te;

void ins(int x,int y)
{
     a[++tot].num=y;
     a[tot].next=str[x];
     str[x]=tot;
}

int cmp(const void*a,const void*b)
{
    int c=*(int*)a,d=*(int*)b;
    if (deep[c]<deep[d]) return -1;
    if (deep[c]>deep[d]) return 1;
    return 0;
}

int main()
{
    freopen("tree.in","r",stdin);
    freopen("tree.out","w",stdout);
    
    scanf("%d",&n);
    for (int i=1;i<n;++i)
    {
        scanf("%d%d",&u,&v);
        ins(u,v);
        ins(v,u);
    }
    
    sta[0]=1;
    e[0]=str[1];
    father[1]=0;
    while (top>=0)
    {
          te=e[top];
          if (!te) --top;
          else
          {
              v=sta[top];
              u=a[te].num;
              e[top]=a[te].next;
              if (u!=father[v])
              {
                          sta[++top]=u;
                          e[top]=str[u];
                          deep[u]=deep[v]+1;
                          father[u]=v;
              }
          }
    }
    
    for (int i=1;i<=n;++i) c[i]=i;
    deep[0]=-1;
    qsort(c,n+1,sizeof(int),cmp);
    for (int i=n;i>0;--i)
    {
        u=c[i];
        te=str[u];
        if (!te) continue;
        p=0;
        do
        {
                 v=a[te].num;
                 if (father[u]!=v)
                    if (f[v]+1>f[u])
                    {
                                  p=f[u];
                                  f[u]=f[v]+1;
                    }
                    else 
                         if (f[v]+1>p) p=f[v]+1;
                 te=a[te].next;
        }
        while (te);
        if (f[u]+p>ans) ans=f[u]+p;
    }
    
    printf("%d\n",ans);
    
    return 0;
}

 

 

相关阅读 更多 +
排行榜 更多 +
三角符文第一章下载

三角符文第一章下载

角色扮演 下载
嘀嘀动画官方正版下载

嘀嘀动画官方正版下载

趣味娱乐 下载
像素世界僵尸危机安卓版

像素世界僵尸危机安卓版

飞行射击 下载