[BZOJ2286] [Sdoi2011]消耗战
来源:互联网 发布:网络博客大全评级 编辑:程序博客网 时间:2024/05/20 02:51
传送门
http://www.lydsy.com/JudgeOnline/problem.php?id=2286
题目大意
给定一棵树,树上有边权,切断一条边消耗边权大小的能量
每次给定一些关键点,使这些关键点都不能与1联通,询问最小代价
题解
树形DP
复杂度
我们发现其实不用每次都对整棵树做一遍
(下面的父子关系是省略无关点后的新树)
其中
可以用ST表预处理出来做到每次
(这一种抛去无关点建立的新树通常叫做虚树)
如何建立,看下面一段
接下来所说的”树”均指虚树,原来那棵树叫做”原树”.
构建过程如下:
按照原树的dfs序号(记为dfn)递增顺序遍历选择的节点. 每次遍历节点都把这个节点插到树上.
首先虚树一定要有一个根. 随便扯一个不会成为询问点的点作根.
维护一个栈,它表示在我们已经(用之前的那些点)构建完毕的虚树上,以最后一个插入的点为端点的DFS链.
设最后插入的点为p(就是栈顶的点),当前遍历到的点为x.我们想把x插入到我们已经构建的树上去.
求出lca(p,x),记为lca.有两种情况:
1.p和x分立在lca的两棵子树下.
2.lca是p.
(为什么lca不能是x?
因为如果lca是x,说明dfn(lca)=dfn(x)
const maxn=250000;var w:array[0..3*maxn,1..3]of longint; dp:array[0..maxn]of int64; pos,dep,t,s,v,p:array[0..maxn]of longint; st:array[0..maxn,0..20]of longint; dis:array[0..maxn,0..20]of int64; i,j,k:longint; n,m,len,a,b,c,tt:longint;function min(a,b:int64):int64;begin if a>b then exit(b) else exit(a); end;procedure init(a,b,c:longint);begin w[len,1]:=b; w[len,2]:=c; if w[a,3]=0 then w[a,3]:=len else w[w[a,1],3]:=len; w[a,1]:=len; inc(len);end;procedure sort(l,r:longint);var i,j,a,b:longint;begin i:=l;j:=r;a:=pos[s[(l+r)div 2]]; repeat while (pos[s[i]]<a) do inc(i); while (pos[s[j]]>a) do dec(j); if not(i>j) then begin b:=s[i]; s[i]:=s[j]; s[j]:=b; inc(i); dec(j); end; until i>j; if l<j then sort(l,j); if i<r then sort(i,r);end;procedure dfs(a:longint);var tt:longint;begin tt:=w[a,3]; inc(len); pos[a]:=len; while tt<>0 do begin if (w[tt,1]<>st[a,0]) then begin dep[w[tt,1]]:=dep[a]+1; st[w[tt,1],0]:=a; dis[w[tt,1],0]:=w[tt,2]; dfs(w[tt,1]); end; tt:=w[tt,3]; end;end;procedure prepare;var i:longint;begin len:=0; dep[1]:=1; dfs(1); for i:=1 to 20 do for j:=1 to n do st[j,i]:=st[st[j,i-1],i-1]; for i:=1 to 20 do for j:=1 to n do dis[j,i]:=min(dis[j,i-1],dis[st[j,i-1],i-1]);end;function lca(a,b:longint):longint;var i:longint;begin if dep[a]<dep[b] then begin i:=a; a:=b; b:=i; end; for i:=20 downto 0 do if dep[st[a,i]]>=dep[b] then a:=st[a,i]; if a=b then exit(a); for i:=20 downto 0 do if st[a,i]<>st[b,i] then begin a:=st[a,i]; b:=st[b,i]; end; exit(st[a,0]);end;function distance(a,b:longint):int64;var ans:int64; i:longint;begin if dep[a]<dep[b] then begin i:=a; a:=b; b:=i; end; ans:=maxlongint; for i:=20 downto 0 do if dep[st[a,i]]>=dep[b] then begin ans:=min(ans,dis[a,i]); a:=st[a,i]; end; exit(ans);end;begin readln(n); len:=n+1; for i:=1 to n-1 do begin readln(a,b,c); init(a,b,c); init(b,a,c); end; prepare; readln(m); for i:=1 to m do begin read(a); for j:=1 to a do begin read(s[j]); v[s[j]]:=1; end; sort(1,a); t[1]:=1; t[0]:=1; p[0]:=1; p[1]:=1; len:=n+1; for j:=1 to a do begin tt:=lca(t[t[0]],s[j]); if tt=t[t[0]] then begin inc(t[0]); t[t[0]]:=s[j]; inc(p[0]); p[p[0]]:=s[j]; end else begin while dep[t[t[0]-1]]>dep[tt] do begin if v[t[t[0]]]=1 then inc(dp[t[t[0]-1]],distance(t[t[0]],t[t[0]-1])) else inc(dp[t[t[0]-1]],min(distance(t[t[0]],t[t[0]-1]),dp[t[t[0]]])); dp[t[t[0]]]:=0; dec(t[0]); end; if v[t[t[0]]]=1 then inc(dp[tt],distance(tt,t[t[0]])) else inc(dp[tt],min(distance(tt,t[t[0]]),dp[t[t[0]]])); dp[t[t[0]]]:=0; dec(t[0]); if t[t[0]]<>tt then begin inc(t[0]); t[t[0]]:=tt; inc(p[0]); p[p[0]]:=s[j]; end; inc(t[0]); t[t[0]]:=s[j]; inc(p[0]); p[p[0]]:=s[j]; end; end; while t[0]>1 do begin if v[t[t[0]]]=1 then inc(dp[t[t[0]-1]],distance(t[t[0]],t[t[0]-1])) else begin inc(dp[t[t[0]-1]],min(distance(t[t[0]],t[t[0]-1]),dp[t[t[0]]])); dp[t[t[0]]]:=0; end; dec(t[0]); end; writeln(dp[1]); for j:=1 to p[0] do dp[p[j]]:=0; for j:=1 to a do v[s[j]]:=0; end;end.
- bzoj2286: [Sdoi2011]消耗战
- bzoj2286[Sdoi2011消耗战
- [BZOJ2286] [Sdoi2011]消耗战
- [BZOJ2286][SDOI2011]消耗战
- BZOJ2286: [Sdoi2011]消耗战
- bzoj2286: [Sdoi2011消耗战
- bzoj2286【SDOI2011】消耗战
- BZOJ2286: [Sdoi2011]消耗战
- bzoj2286 [Sdoi2011]消耗战
- [BZOJ2286][Sdoi2011消耗战] 虚树
- BZOJ2286: [Sdoi2011]消耗战 虚树
- 【bzoj2286】[Sdoi2011]消耗战
- bzoj2286 [Sdoi2011]消耗战
- 【bzoj2286】【SDOI2011】消耗战
- 【bzoj2286】【sdoi2011】【消耗战】【虚树+dp】
- 【bzoj2286】[Sdoi2011消耗战 虚树+dp
- [虚树dp] bzoj2286: Sdoi2011消耗战
- BZOJ2286: [Sdoi2011]消耗战(虚树)
- web开发
- Struts2中DMI(动态方法调用)的一些问题
- java 接口实现简单并能说明问题的例子
- UtalPTR 运行报错 Didn't find class "in.srain.cube.image.CubeImageView" on path: DexPathList[[zip file
- VIM配置显示行号
- [BZOJ2286] [Sdoi2011]消耗战
- disksim raid 部分源代码解析
- 相对误差的传递
- TCP/IP基础(二)
- PHP实现冒泡、选择、插入和快速排序
- gravity 与layout_gravity的区别
- POJ 2778 DNA Sequence 题解&代码
- JAVA的包装类 http://blog.csdn.net/hjf19790118/article/details/7081925
- 节点动作