1. 程式人生 > >【NOIP2018提高組D2T3】保衛王國

【NOIP2018提高組D2T3】保衛王國

抱歉,本人蒟蒻沒能做出,不過可給標程,orz大佬
在這裡插入圖片描述

const maxn=100000;inf=trunc(1e+12)-1;
var
f : array[0..maxn,0..17,0..1,0..1]of int64;
up,dw : array[0..maxn,0..1]of int64;
fa : array[0..maxn,0..17]of longint;
go,nxt : array[1..maxn*2]of longint;
dep,head,p : array[0..maxn]of longint;
i,j,n,m,x,y,a,b,tail,f1,w : longint;
function min
(a,b:int64):int64; begin if a<b then exit(a); exit(b); end; procedure add(u,v:longint); begin inc(tail);go[tail]:=v; nxt[tail]:=head[u];head[u]:=tail; end; procedure dfs1(x:longint); var i:longint; begin dw[x,1]:=p[x];dw[x,0]:=0; dep[x]:=dep[fa[x,0]]+1;i:=head[x]; while i<>0 do begin if
go[i]<>fa[x,0] then begin fa[go[i],0]:=x;dfs1(go[i]); dw[x,0]:=dw[x,0]+dw[go[i],1]; dw[x,1]:=dw[x,1]+min(dw[go[i],1],dw[go[i],0]); end;i:=nxt[i]; end; end; procedure dfs2(x:longint); var i:longint; begin i:=head[x]; while i<>0 do begin if go[i]<>fa[x,0] then begin up[
go[i],0]:=up[x,1]+dw[x,1]-min(dw[go[i],1],dw[go[i],0]); up[go[i],1]:=min(up[go[i],0],up[x,0]+dw[x,0]-dw[go[i],1]); dfs2(go[i]); end;i:=nxt[i]; end; end; function lca(x,a,y,b:longint):int64; var tx,dx,ty,dy : array[0..1]of int64;//t=top ans1,ans2 : int64; i,j,k : longint; begin if dep[x]<dep[y] then begin i:=x;x:=y;y:=i;i:=a;a:=b;b:=i; end; tx[a]:=dw[x,a];tx[1-a]:=inf; ty[b]:=dw[y,b];ty[1-b]:=inf; i:=17; while dep[x]>dep[y] do begin while dep[fa[x,i]]<dep[y] do dec(i); dx[0]:=inf;dx[1]:=inf; for k := 0 to 1 do for j := 0 to 1 do dx[j]:=min(dx[j],tx[k]+f[x,i,k,j]); tx:=dx; x:=fa[x,i]; end; if x=y then exit(tx[b]+up[y,b]); i:=17; while fa[x,0]<>fa[y,0] do begin while fa[x,i]=fa[y,i] do dec(i); dx[0]:=inf;dx[1]:=inf;dy:=dx; for k := 0 to 1 do for j := 0 to 1 do begin dx[j]:=min(dx[j],tx[k]+f[x,i,k,j]); dy[j]:=min(dy[j],ty[k]+f[y,i,k,j]); end; tx:=dx;ty:=dy; x:=fa[x,i];y:=fa[y,i]; end; // writeln(x,' ',y,' ',tx[0],' ',tx[1],' ',ty[0],' ',ty[1],' jump!!'); k:=fa[x,0]; ans1:=dw[k,1]-min(dw[x,1],dw[x,0])-min(dw[y,1],dw[y,0]) +min(tx[0],tx[1])+min(ty[0],ty[1])+up[k,1]; ans2:=dw[k,0]-dw[x,1]-dw[y,1]+tx[1]+ty[1]+up[k,0]; exit(min(ans1,ans2)); end; begin assign(input,'defense.in');reset(input); assign(output,'defense.out');rewrite(output); readln(n,m); for i := 1 to n do read(p[i]); for i := 1 to n-1 do begin readln(x,y); add(x,y);add(y,x); end; dfs1(1); dfs2(1); for i := 1 to n do begin f[i,0,0,0]:=inf; f[i,0,0,1]:=dw[fa[i,0],1]-min(dw[i,1],dw[i,0]); f[i,0,1,0]:=dw[fa[i,0],0]-dw[i,1]; f[i,0,1,1]:=f[i,0,0,1]; end; for j := 1 to 17 do for i := 1 to n do begin f1:=fa[i,j-1]; fa[i,j]:=fa[f1,j-1]; for x := 0 to 1 do for y := 0 to 1 do begin f[i,j,x,y]:=inf; for w := 0 to 1 do f[i,j,x,y]:=min(f[i,j,x,y],f[i,j-1,x,w]+f[f1,j-1,w,y]); // writeln(i,' ',fa[i,j],' ',x,' ',y,' : ',f[i,j,x,y]); end; end; for i := 1 to m do begin readln(x,a,y,b); if (a+b=0)and((fa[y,0]=x)or(fa[x,0]=y)) then begin writeln(-1);continue;end; writeln(lca(x,a,y,b)); end; close(input);close(output); end.