很明显,20%=mincut 40%=每次暴力树形dp
那么正解是什么呢?不难发现∑ki<=500000,也就是每次询问的复杂度都要跟k有关
从树形dp工作的角度来看,确实有很多点我们根本就没必要访问,我们设每次要割断的岛屿为关键点
这里引入了一个新的东西叫做虚树,简单来说就是把树上没用的点去掉收缩成一棵树
具体来说,如果一个点的子树中至多只有一棵子树包含关键点,那么这个点就可以删掉
也就是说只有关键点和他们的lca会被保留下来就行了,证明总点数<=2*k-1
那么怎么构建虚树?我们先按dfs序排序,然后按这个顺序不断加点维护虚树上最新的路径
感觉建树的方法只可意会不可言传,具体见代码吧……

 type node=record
len,po,next:longint;
end; var e:array[..] of node;
anc:array[..,..] of longint;
b,d,p,c,fa,st,a:array[..] of longint;
f:array[..] of int64;
v:array[..] of boolean;
w,s,m,h,t,n,len,i,x,y,z:longint; function min(a,b:longint):longint;
begin
if a>b then exit(b) else exit(a);
end; procedure swap(var a,b:longint);
var c:longint;
begin
c:=a;
a:=b;
b:=c;
end; procedure sort(l,r: longint);
var i,j,x:longint;
begin
i:=l;
j:=r;
x:=b[a[(l+r) shr ]];
repeat
while b[a[i]]<x do inc(i);
while x<b[a[j]] do dec(j);
if not(i>j) then
begin
swap(a[i],a[j]);
inc(i);
j:=j-;
end;
until i>j;
if l<j then sort(l,j);
if i<r then sort(i,r);
end; procedure add(x,y,z:longint);
begin
inc(len);
e[len].po:=y;
e[len].len:=z;
e[len].next:=p[x];
p[x]:=len;
end; procedure dfs(x:longint);
var i,y:longint;
begin
inc(t);
b[x]:=t; //dfs序
for i:= to h do
begin
y:=anc[x,i-];
if y<> then anc[x,i]:=anc[y,i-]
else break;
end;
i:=p[x];
while i<> do
begin
y:=e[i].po;
if fa[x]<>y then
begin
fa[y]:=x;
anc[y,]:=x;
c[y]:=min(c[x],e[i].len); //c[]表示把这个点和根节点割开最小代价
d[y]:=d[x]+;
dfs(y);
end;
i:=e[i].next;
end;
end; function lca(x,y:longint):longint;
var i,p:longint;
begin
if d[x]<d[y] then swap(x,y);
p:=trunc(ln(d[x])/ln());
if d[x]>d[y] then
for i:=p downto do
if d[x]- shl i>=d[y] then x:=anc[x,i];
if x=y then exit(x);
for i:=p downto do
if (anc[y,i]<>anc[x,i]) then
begin
x:=anc[x,i];
y:=anc[y,i];
end;
exit(fa[x]);
end; procedure dp(x:longint); //dp过程很简单
var i,y:longint;
s:int64;
begin
if x= then f[]:=*
else f[x]:=c[x];
i:=p[x];
s:=;
while i<> do
begin
y:=e[i].po;
dp(y);
s:=s+f[y];
i:=e[i].next;
end;
p[x]:=;
if (s<>) then
if f[x]>s then f[x]:=s;
end; begin
readln(n);
h:=trunc(ln(n)/ln());
for i:= to n- do
begin
readln(x,y,z);
add(x,y,z);
add(y,x,z);
end;
c[]:=;
dfs();
readln(m);
fillchar(p,sizeof(p),);
while m> do
begin
dec(m);
read(s);
for i:= to s do
read(a[i]); sort(,s);
w:=;
for i:= to s do
if lca(a[w],a[i])<>a[w] then //这里一点点优化,如果存在祖先关系的关键点,肯定割祖先以上的边
begin
inc(w);
a[w]:=a[i];
end;
len:=;
st[]:=;
t:=;
for i:= to w do
begin
x:=a[i];
z:=lca(x,st[t]);
while d[z]<d[st[t]] do //这里画个图比较好理解,类似一个新路径和原来维护的路径的一个分叉
begin
if d[z]>=d[st[t-]] then
begin
add(z,st[t],);
dec(t);
if st[t]<>z then
begin
inc(t);
st[t]:=z;
end;
break;
end;
add(st[t-],st[t],); //把原来分叉的那段建出来
dec(t);
end;
if st[t]<>x then
begin
inc(t);
st[t]:=x;
end;
end;
while t> do //把维护的路径建出来
begin
add(st[t-],st[t],);
dec(t);
end;
dp();
writeln(f[]);
end;
end.

bzoj2286的更多相关文章

  1. 【bzoj2286】 消耗战

    http://www.lydsy.com/JudgeOnline/problem.php?id=2286 (题目链接) 一个小小的细节,WA了一天,欲哭无泪了.. 题意 给出一个n个节点的带权树,总共 ...

  2. [bzoj2286][Sdoi 2011]消耗战

    [bzoj2286]消耗战 标签: 虚树 DP 题目链接 题解 很容易找出\(O(mn)\)的做法. 只需要每次都dp一遍. 但是m和n是同阶的,所以这样肯定会T的. 注意到dp的时候有很多节点是不需 ...

  3. 【BZOJ2286】消耗战(虚树,动态规划)

    [BZOJ2286]消耗战(虚树,动态规划) 题面 BZOJ Description 在一场战争中,战场由n个岛屿和n-1个桥梁组成,保证每两个岛屿间有且仅有一条路径可达.现在,我军已经侦查到敌军的总 ...

  4. [BZOJ2286][SDOI2011]消耗战(虚树DP)

    2286: [Sdoi2011]消耗战 Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 4998  Solved: 1867[Submit][Statu ...

  5. 【BZOJ2286】[Sdoi2011]消耗战 虚树

    [BZOJ2286][Sdoi2011]消耗战 Description 在一场战争中,战场由n个岛屿和n-1个桥梁组成,保证每两个岛屿间有且仅有一条路径可达.现在,我军已经侦查到敌军的总部在编号为1的 ...

  6. 【BZOJ2286】消耗战(虚树,DFS序,树形DP)

    题意:一棵N个点的树上有若干个关键点,每条边有一个边权,现在要将这些关键点到1的路径全部切断,切断一条边的代价就是边权. 共有M组询问,每组询问有k[i]个关键点,对于每组询问求出完成任务的最小代价. ...

  7. 虚树+【BZOJ2286】【SDOI2011】消耗战(虚树)(DP)

    先看一道题: [BZOJ2286][SDOI2011]消耗战 Description 在一场战争中,战场由n个岛屿和n−1个桥梁组成,保证每两个岛屿间有且仅有一条路径可达.现在,我军已经侦查到敌军的总 ...

  8. [BZOJ2286][Sdoi2011]消耗战(虚树上DP)

    2286: [Sdoi2011]消耗战 Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 6457  Solved: 2533[Submit][Statu ...

  9. 【学习笔记】虚树复习记(BZOJ2286 SDOI2011 消耗战)

    想写战略游戏却想不起来虚树T^T 所以就有了这篇复习记QwQ ——简介!—— 我们在处理树上问题的时候,dfs是一个常用手段,但是我们发现,如果一棵树上只有一部分关键点,每次dfs需要访问好多不是关键 ...

  10. bzoj2286 消耗战

    还是虚树的题目啊... 如果只有一个询问,我们这么考虑,可以设dp[x]为只删除x子树内和x到父亲的边,使得x这棵子树内的能源岛屿都与x的父亲不连通的最小花费. 这样如果x本身是能源岛屿,那么dp[x ...

随机推荐

  1. OC1_银行账户类

    // // BankAccount.h // OC1_银行账户类 // // Created by zhangxueming on 15/6/10. // Copyright (c) 2015年 zh ...

  2. Windows10中的IIS10安装php manager和IIS URL Rewrite 2.0组件的方法

    Windows10中自带的Server:Microsoft-IIS/10.0,然后这个10却让原本支持组件无法安装了,php manager组件安装时提示“必须安装IIS7以上才可以安装”.那是不是真 ...

  3. Linux中的简单命令

    history:打印你输过的命令      1.用户在shell中输入的命令会自动保存到内存缓冲区      2.在退出shell的时候,内存中的数据会刷新到磁盘文件:~/.bash_history ...

  4. zoj 3829 Known Notation

    作者:jostree 转载请说明出处 http://www.cnblogs.com/jostree/p/4020792.html 题目链接: zoj 3829 Known Notation 使用贪心+ ...

  5. Less使用——让老司机带你飞

    为什么我要使用Less less的作为编写css的工具插件,省时.方便.检测,具体的安装,请参考我的一篇文章<sublime text3 个人使用心得>,里面我讲解了安装方法,使用webs ...

  6. 今日吐槽20151208.net服务器控件

    正文 今天有个小任务是给页面添加一个搜索条件,复选框多选.因为页面都是服务器控件,我也只能用服务器控件配合了.然后给页面加了一个  CheckBoxList  控件.后台通过数据表加载数据. fore ...

  7. 怎样用sourceTree将自己本地的项目上传到github网站上

    前言:GitHub 是基于 Git 的一个代码托管网站.开发者可以将代码在 GitHub 上开源,可以浏览其它项目的代码. 准备工作:1.github网站账号.2.sourceTree软件. 一.在g ...

  8. Android开发框架

    AsyncHttpClient 它把HTTP所有的通信细节全部封装在了内部,我们只需要简单调用几行代码就可以完成通信操作 Universal-Image-Loader 它使得在界面上显示网络图片的操作 ...

  9. 【python】坑,坑,折腾一个下午python 3.5中 ImportError: No module named BeautifulSoup

    将语句 from bs4 import BeautifulSoup4 改成 from bs4 import BeautifulSoup 通过 尼玛------------------------! 总 ...

  10. Sublime Text 3插件之Emmet:HTML/CSS代码快速编写神器

    一.快速编写HTML代码 1.  初始化 HTML文档需要包含一些固定的标签,比如<html>.<head>.<body>等,现在你只需要1秒钟就可以输入这些标签. ...