CF1037D Valid BFS?
玄学的题目。。。。
题目大意:
告诉你一棵树,再告诉你一个bfs序,问这个bfs序对于这棵树是否合法(从1开始bfs)
拿到这道题的第一感觉发现好像有点麻烦,直接跑个bfs,看看一不一样(貌似还有一大堆的限制)
开始换算法
emmm,经过一段时间的思考,发现直接对着那个bfs序跑一边不就好了吗???
从1开始,我们知道它的孩子一定出现已知的一段区间内,如果这个bfs序合法,那么它的孩子一定在这一段区间中都出现了一次
var u,v,tot,l,r,i,j,n:longint; num,fa,head,x,vet,next,size:array[0..400000] of longint; //num[i]表示结点i上一次是被哪个点拓展的 procedure add(u,v:longint);//链式前向星存边 begin inc(tot); next[tot]:=head[u]; head[u]:=tot; vet[tot]:=v; end; procedure dfs(id,father:longint); var point:longint; begin fa[id]:=father;//给边定向 point:=head[id]; while point<>0 do begin if (vet[point]<>father) then begin dfs(vet[point],id); inc(size[id]);//求结点id孩子的数量 end; point:=next[point]; end; end; begin readln(n); for i:=1 to n-1 do begin readln(u,v); add(u,v); add(v,u); end; for i:=1 to n do read(x[i]); dfs(1,0); l:=1; r:=1; if x[1]<>1 then begin writeln('NO'); halt; end;//特判第一个是不是1 for i:=1 to n do begin l:=r+1; r:=l+size[x[i]]-1; //当前这段区间l一定来源于上一段区间r+1,拓展结点便是x[i],长度是x[i]的儿子数量 for j:=l to r do num[x[j]]:=i; //计数 j:=head[x[i]]; while j<>0 do begin if (vet[j]<>fa[x[i]]) and (num[vet[j]]<>i) then begin writeln('NO'); halt; end; j:=next[j]; end; end; writeln('YES'); end.
(初赛真的要GG了呀,QAQ,我还小不想AFO)