hdu 4607 树的直径

思路:利用dfs遍历整棵树,找出最长子树与次长子树,两者的和最大就是直径。

若k值小于直径就输出k-1,否则输出(k-d-1)*2+d;

#include<iostream>

#include<cstdio>

#include<cstring>

#include<algorithm>

#define Maxn 1000010

using namespace std;

int vi[Maxn],head[Maxn],ans,e;

struct Edge{

    int u,v,next,val;

}edge[Maxn];

void init()

{

    e=0;

    memset(head,-1,sizeof(head));

    ans=0;

    memset(vi,0,sizeof(vi));

}

void add(int u,int v,int val)

{

    edge[e].u=u,edge[e].v=v,edge[e].val=val,edge[e].next=head[u],head[u]=e++;

    edge[e].v=u,edge[e].u=v,edge[e].val=val,edge[e].next=head[v],head[v]=e++;

}

int dfs(int u)

{

    vi[u]=1;

    int i,j,temp=0,Max=0,lMax=0;

    for(i=head[u];i!=-1;i=edge[i].next)

    {

        if(!vi[edge[i].v])

        {

            temp=dfs(edge[i].v);

            if(temp+1>=Max)

            {

                lMax=Max;

                Max=temp+1;

            }

            else

            {

                if(temp+1>lMax)

                    lMax=temp+1;

            }

            if(Max+lMax>ans)

                ans=Max+lMax;

        }

    }

    return Max;

}

int main()

{

    int i,j,n,m,a,b,t;

    scanf("%d",&t);

    while(t--)

    {

        init();

        scanf("%d%d",&n,&m);

        for(i=1;i<n;i++)

        {

            scanf("%d%d",&a,&b);

            add(a,b,1);

        }

        int temp=dfs(1);

        //if(temp+1>ans)

           // ans=temp+1;

        for(i=1;i<=m;i++)

        {

            scanf("%d",&a);

            if(a<=ans+1)

                printf("%d\n",a-1);

            else

                printf("%d\n",(a-ans-1)*2+ans);

        }

    }

    return 0;

}

 

你可能感兴趣的:(HDU)