zoukankan      html  css  js  c++  java
  • 【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.
    
    转载需注明出处。
  • 相关阅读:
    分形与数据结构第一篇(神奇的色子)
    画图小工具第二篇
    画图小工具第一篇
    图形界面第一篇
    回合制对战游戏第二篇
    回合对战制游戏第一篇(初识java)
    技术+态度+人品
    排序的一些方法(稳定性,内外排序,时间空间复杂度)
    暂时性死区
    vue传值(父子传值,非父子传值)
  • 原文地址:https://www.cnblogs.com/jz929/p/11817835.html
Copyright © 2011-2022 走看看