hdu4607

来源:互联网 发布:linux重启网卡命令 编辑:程序博客网 时间:2024/05/16 03:40
/*
分析:
    2013multi第一场h题,tree dp。
    水题,难点儿是怎么找到树里面最长的路径。维护到最远的儿子的距
离(是儿子孙子什么的、祖先不算),然后就没什么说的了、看代码吧。
    我在看别的题,队友想到的思路、难点告诉了我,tree dp么,搞之~。
    375ms,没想到statistic里面排的还挺高的囧~

                                         2013-07-23
*/






#include"iostream"#include"cstdio"#include"cstring"using namespace std;const int N=100001;const int M=200002;int n,m,k,dp[N],ans;int flag[N];struct Edge{int v,next;}edge[M];int tot,head[N];void add(int a,int b){edge[tot].v=b;edge[tot].next=head[a];head[a]=tot++;edge[tot].v=a;edge[tot].next=head[b];head[b]=tot++;}inline int max(int a,int b){return a>b?a:b;}void dfs(int k){int j,v;flag[k]=1;for(j=head[k];j!=-1;j=edge[j].next){v=edge[j].v;if(flag[v])continue;dfs(v);dp[k]=max(dp[k],dp[v]+1);if(ans<dp[k])ans=dp[k];break;}if(j==-1)return ;for(j=edge[j].next;j!=-1;j=edge[j].next){v=edge[j].v;if(flag[v])continue;dfs(v);ans=max(ans,dp[k]+dp[v]+1);dp[k]=max(dp[k],dp[v]+1);}ans=max(ans,dp[k]);}int main(){int T;int i;int a,b;cin>>T;while(T--){cin>>n>>m;tot=0;memset(head,-1,sizeof(head));for(i=1;i<n;i++){scanf("%d%d",&a,&b);add(a,b);}ans=0;memset(dp,0,sizeof(dp));memset(flag,0,sizeof(flag));dfs(1);while(m--){scanf("%d",&k);if(ans+1>=k)printf("%d\n",k-1);elseprintf("%d\n",ans+(k-ans-1)*2);}}return 0;}


原创粉丝点击