hdu 4607 (树形DP)

来源:互联网 发布:淘宝店铺搜索搜不出来 编辑:程序博客网 时间:2024/05/21 06:54

当时比赛的时候我们找出来只要求出树的最长的边的节点数ans,如果要访问点的个数n小于ans距离直接就是n-1

如果大于的话就是(n-ans)*2+ans-1,当时求树的直径难倒我们了,都不会树形dp

选一个点当根每次求出一点到子节点的最大距离和次大距离,两个的和最大的就是树的直径

还在网上看到一种方法,任意一点广搜达到最远点max,再从max广搜,到达最远点就是树的直径

自己想了想这种方法:如果中间有点有分支的话,那么这点的最大分支一定是到max的

但是它的次大分支就不一定是到起点的,所以从max搜的话肯定是到这点的次大分支,就是直径了



#include<stdio.h>#include<string.h>#define N 100001int head[N],num,ins[N],n;struct edge{    int ed,next;}E[N*2];void addedge(int x,int y){    E[num].ed=y;    E[num].next=head[x];    head[x]=num++;}int dis;int dist(int u){    ins[u]=1;    int max=0,mmax=0;    for(int i=head[u];i!=-1;i=E[i].next)    {        int v=E[i].ed;        if(ins[v]==1)continue;        int temp=dist(v);        if(temp>mmax)        {            max=mmax;            mmax=temp;                    }        else if(temp>max)        {            max=temp;        }    }    if(dis<(mmax+max+1))        dis=mmax+max+1;    return mmax+1;}int main(){    int i,m,x,y,t;    scanf("%d",&t);    while(t--)    {        scanf("%d%d",&n,&m);        memset(head,-1,sizeof(head));        num=0;        for(i=0;i<n-1;i++)        {            scanf("%d%d",&x,&y);            addedge(x,y);            addedge(y,x);        }        memset(ins,0,sizeof(ins));        dis=0;        dist(1);        for(i=1;i<=m;i++)        {            scanf("%d",&x);            if(x<=dis)                printf("%d\n",x-1);            else printf("%d\n",dis+(x-dis)*2-1);        }    }    return 0;}



#include<stdio.h>#include<queue>#include<string.h>#define N 100001using namespace std;int head[N],num,vis[N],n;struct edge{    int ed,next;}E[N*2];struct node{int x,w;}cur,next;void addedge(int x,int y){    E[num].ed=y;    E[num].next=head[x];    head[x]=num++;}int dist(){int i,v;memset(vis,0,sizeof(vis));queue<node>Q1,Q2;cur.x=1;Q1.push(cur);while(!Q1.empty()){       cur=Q1.front();   Q1.pop();   vis[cur.x]=1;   for(i=head[cur.x];i!=-1;i=E[i].next)   {   next.x=v=E[i].ed;   if(vis[v]==0)   Q1.push(next);   }}cur.w=1;Q2.push(cur);//广搜最后出来的点一点是最远点memset(vis,0,sizeof(vis));while(!Q2.empty()){cur=Q2.front();Q2.pop();vis[cur.x]=1;for(i=head[cur.x];i!=-1;i=E[i].next){next.x=v=E[i].ed;next.w=cur.w+1;if(vis[v]==0)  Q2.push(next);}}return cur.w;}int main(){    int i,m,x,y,t;    scanf("%d",&t);    while(t--)    {        scanf("%d%d",&n,&m);        memset(head,-1,sizeof(head));        num=0;        for(i=0;i<n-1;i++)        {            scanf("%d%d",&x,&y);            addedge(x,y);            addedge(y,x);        }        int dis=dist();        for(i=1;i<=m;i++)        {            scanf("%d",&x);            if(x<=dis)                printf("%d\n",x-1);            else printf("%d\n",dis+(x-dis)*2-1);        }    }    return 0;}


原创粉丝点击