第四题

来源:互联网 发布:office for mac 激活 编辑:程序博客网 时间:2024/05/21 09:13

题目描述

 “尼伯龙根是一棵由n-1条高架路连起n 个地区的树,每一次Load,你都会重生在某一个地区。如果重生点是整个尼伯龙根的重心,也就是这个树的重心,那么你就能在最短时间内带诺诺逃脱啦。”
“对了,再给你一点方便咯,你可以选一条高架桥断掉,再连接另外两个地方,每次Load只能用一次技能,而又必须使整个它仍构成树形结构。你的Save点在这里,Load自然会恢复原始的尼伯龙根咯。” 

输入

第一行两个整数n,m,n意义如题,m表示路明非Load了m次。
接下来n-1行,每行两个整数x,y表示节点x,y之间存在一条边。
接下来m行,每行一个整数p,表示这次Load的重生地区。

输出

对于每一个询问,输出一行
如果可以则输出”YES”,否则输出”NO”(注意没有引号)

样例输入

5 31 21 31 41 5123

样例输出

YESNONO

数据范围限制

对于20%的数据 1<=n,m<=50
对于50%的数据 1<=n,m<=3000
对于100%的数据 1<=n,m<=200000
对于此题,只能说不是很难。要搞懂还是很容易的。就是先将这一棵树的重心求出来(找其中一个就好了).用这个点为根重新组装一棵树。我们知道,一棵树的重心的分支上的结点多不会超过N/2。所以,我们可以运用这一特点,当要将一架桥换掉的时候,他的下面结点的是一定不会超过N/2。我们只需要考虑他的上面结点。对于根,他的所有结点数都不会超过N/2,所以,当重组树的根节点不再根的最大结点数的分支中时,我们可以将最大分支直接连到当前根的位置上,这样可以保证剩下的那个边上的结点一定是最小的了;如果在最大结点数的分支中时,取次大的即可。如果剩下的那条边的结点数还是超过了N/2,那么就输出'NO',反之输出'YES'.


代码如下:

var        jl,s,g,a,f,x,y:array[1..400000] of longint;        n,m,dian,i,p,ji,max,max2,jis,ans:longint;        h:array[1..400000,1..100] of longint;        bz,zhi:array[1..400000] of boolean;        bo:boolean;procedure dg(k:longint);var        i,p:longint;begin        if k=12 then          k:=k;        for i:=1 to g[k] do          begin            p:=h[k,i];            if bz[p]=false then              begin                bz[p]:=true;                dg(p);                f[k]:=f[k]+f[p];              end;          end;        f[k]:=f[k]+1;end;procedure dg2(k:longint);var        i,p,t,s:longint;begin        s:=n-f[k];        if bo then          exit;        dec(s);        for i:=1 to g[k] do          begin            p:=h[k,i];            if bz[p] then              continue;            if s<f[p] then              s:=f[p];          end;        if s<=n div 2 then          begin            bo:=true;            dian:=k;            exit;          end        else          begin            for i:=1 to g[k] do              begin                if bz[h[k,i]] then                  continue;                bz[h[k,i]]:=true;                dg2(h[k,i]);                if bo then                  exit;              end;          end;end;procedure jilu(k:longint);var        i,p:longint;begin        zhi[k]:=true;        for i:=1 to g[k] do          begin            p:=h[k,i];            if bz[p]=false then              begin                bz[p]:=true;                jilu(p);              end;          end;end;begin        assign(input,'h3.in');        assign(output,'h3.out');        reset(input);        rewrite(output);        read(n,m);        for i:=1 to n-1  do          begin            read(x[i],y[i]);            inc(g[x[i]]);            h[x[i],g[x[i]]]:=y[i];            inc(g[y[i]]);            h[y[i],g[y[i]]]:=x[i];          end;        for i:=1 to m do          read(a[i]);        fillchar(bz,sizeof(bz),false);        fillchar(f,sizeof(f),0);        bz[x[1]]:=true;        dg(x[1]);        fillchar(bz,sizeof(bz),false);            bo:=false;        bz[x[1]]:=true;        dg2(x[1]);        fillchar(f,sizeof(f),0);        fillchar(bz,sizeof(bz),false);        bz[dian]:=true;        dg(dian);        for i:=1 to g[dian] do          begin            p:=h[dian,i];            if max<f[p] then              begin                max:=f[p];                ji:=p;                jis:=i;              end;          end;        fillchar(bz,sizeof(bz),false);        fillchar(zhi,sizeof(zhi),false);        bz[dian]:=true;        bz[ji]:=true;        ans:=1;        jilu(ji);        for i:=1 to g[dian] do          if i<>jis then            begin              p:=h[dian,i];              if max2<f[p] then                max2:=f[p];            end;        for i:=1 to m do          begin            if a[i]=dian then              begin                writeln('YES');                continue;              end;            if (zhi[a[i]]) then              begin                if n-f[a[i]]-max2<=n div 2 then                  writeln('YES')                else                  writeln('NO');              end            else              begin                if n-f[a[i]]-max<=n div 2 then                  writeln('YES')                else                  writeln('NO');              end;          end;        close(input);        close(output);end.