2286: [Sdoi2011]消耗战


Time Limit: 20 Sec  Memory Limit: 512 MB
Submit: 4896  Solved: 1824
[Submit][Status][Discuss]

Description


在一场战争中,战场由n个岛屿和n-1个桥梁组成,保证每两个岛屿间有且仅有一条路径可达。现在,我军已经侦查到敌军的总部在编号为1的岛屿,而且他们已经没有足够多的能源维系战斗,我军胜利在望。已知在其他k个岛屿上有丰富能源,为了防止敌军获取能源,我军的任务是炸毁一些桥梁,使得敌军不能到达任何能源丰富的岛屿。由于不同桥梁的材质和结构不同,所以炸毁不同的桥梁有不同的代价,我军希望在满足目标的同时使得总代价最小。
侦查部门还发现,敌军有一台神秘机器。即使我军切断所有能源之后,他们也可以用那台机器。机器产生的效果不仅仅会修复所有我军炸毁的桥梁,而且会重新随机资源分布(但可以保证的是,资源不会分布到1号岛屿上)。不过侦查部门还发现了这台机器只能够使用m次,所以我们只需要把每次任务完成即可。

Input


第一行一个整数n,代表岛屿数量。

接下来n-1行,每行三个整数u,v,w,代表u号岛屿和v号岛屿由一条代价为c的桥梁直接相连,保证1<=u,v<=n且1<=c<=100000。

第n+1行,一个整数m,代表敌方机器能使用的次数。

接下来m行,每行一个整数ki,代表第i次后,有ki个岛屿资源丰富,接下来k个整数h1,h2,…hk,表示资源丰富岛屿的编号。

Output


输出有m行,分别代表每次任务的最小代价。

Sample Input



Sample Output



HINT


对于100%的数据,2<=n<=250000,m>=1,sigma(ki)<=500000,1<=ki<=n-1

Source


Stage2 day2

虚树:


既然是虚树的版版题,我就有必要提一下什么是虚树了,虽然我也是今天才学的。但我尽量按自己的理解讲清楚吧

什么是虚树,就是在树上选定一个集合,这个集合间所有点和他们相应lca之间重新组成的树。

设红色点为关键点,让我们来看看最后的虚树

橙色点是虚树中关键点的lca,虚点和虚边就是被去掉了。

这里看起来是两条边,其实合成了一条边

 
虚树,什么时候可以派上用场,就是询问很多,每次询问给定树的一个集合,所有询问集合点数总和不大,且问题可以转化为只和集合关键点有关时。就可以用虚树
 
比如说这道题,我们可以建出虚树,那么就是一个很简单的树形dp了,一个点要么是自己不选,所有儿子选,要么所有儿子都不选自己选。
 
那设一个点选的价值为f[i] ,这个点到1号结点路径上价值最小边为val[i]
那么

最后输出虚树根节点(root)即可。

然后我们还发现一个性质就是一个点是关键点,那么它的儿子结点可以直接忽略。

那么说了这道题怎么做了,就差怎么建出虚树了。

建虚树首先我们dfs一遍原树,建出dfs序。

我们先把关键点按从小到大排序。

然后用一个栈的形式维护一条链。

简单说

如果当前点和栈顶为一条链,那么可以直接加入栈。

如果不为一条链,那么得一直删除栈顶,直到形成一条链。

怎么具体实现呢?

设当前点和栈顶lca为g

那么如果dfn[g] >= dfn[top]那么很显然是一条链,直接push当前点即可

如果dfn[g] < dfn[top]那么不是一条链,边pop,边连边栈顶第二个个元素和栈顶。

知道dfn[g] >= dfn[top - 1],那么把top - 1 和 top连边后加入g即可。

最后一条链没有点去pop它,所以最后还要特殊判断栈内是否还要有一条链。

这样就很方便了。

AC代码:


# include <iostream>
# include <cstdio>
# include <cstring>
# include <algorithm>
using namespace std;
typedef long long LL;
const int N = 6e5 + ;
const LL inf = 1e15;
int hson[N],sz[N],dep[N],top[N],id[N],fa[N];LL f[N];
int head[N],dt,tot,que[N],n,m,k,a[N],cnt;LL w[N];
struct Edge{
int to,nex;LL w;
}edge[N << ];
void AddEdge(int u,int v,LL w)
{
if(u == v)return;
edge[++dt] = (Edge){v,head[u],w};
head[u] = dt;
}
void dfs(int u)
{
sz[u] = ;
for(int i = head[u];i;i = edge[i].nex)
{
if(sz[edge[i].to])continue;
dep[edge[i].to] = dep[u] + ;
fa[edge[i].to] = u;
w[edge[i].to] = min(w[u],edge[i].w);
dfs(edge[i].to);
sz[u] += sz[edge[i].to];
if(sz[hson[u]] < sz[edge[i].to])hson[u] = edge[i].to;
}
}
void dfs(int u,int tp)
{
top[u] = tp;id[u] = ++tot;
if(hson[u])dfs(hson[u],tp);
for(int i = head[u];i;i = edge[i].nex)
if(!id[edge[i].to])dfs(edge[i].to,edge[i].to);
head[u] = ;
}
int lca(int u,int v)
{
while(top[u] != top[v])
{
if(dep[top[u]] < dep[top[v]])swap(u,v);
u = fa[top[u]];
}
return dep[u] < dep[v] ? u : v;
}
bool cmp(int x,int y){return id[x] < id[y];}
void dp(int u)
{
LL val = ;f[u] = w[u];
for(int i = head[u];i;i = edge[i].nex)
dp(edge[i].to),val += f[edge[i].to];
if(val)f[u] = val < f[u] ? val : f[u];
head[u] = ;
}
void solve()
{ scanf("%d",&k);cnt = ;int g,top;dt = ;
for(int i = ;i <= k;i++)scanf("%d",&a[i]);
sort(a + ,a + k + ,cmp);
for(int i = ;i <= k;i++)if(lca(a[i],a[cnt]) != a[cnt])a[++cnt] = a[i];
que[top = ] = ;
for(int i = ;i <= cnt;i++)
{
g = lca(a[i],que[top]);
while()
{
if(dep[que[top - ]] <= dep[g])
{
AddEdge(g,que[top],);top--;
if(que[top] != g)que[++top] = g;
break;
}
AddEdge(que[top - ],que[top],);top--;
}
if(que[top] != a[i])que[++top] = a[i];
}
top--;
while(top)AddEdge(que[top],que[top + ],),top--;
dp();
printf("%lld\n",f[]);
}
int main()
{
scanf("%d",&n);int x,y;LL z;w[] = inf;
for(int i = ;i < n;i++)
{
scanf("%d %d %lld",&x,&y,&z);
AddEdge(x,y,z);AddEdge(y,x,z);
}
dfs();dfs(,);
scanf("%d",&m);
while(m--)solve();
}

[Bzoj2286][Sdoi2011]消耗战(虚树模板题附讲解)的更多相关文章

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

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

  2. bzoj2286: [Sdoi2011]消耗战 虚树

    在一场战争中,战场由n个岛屿和n-1个桥梁组成,保证每两个岛屿间有且仅有一条路径可达.现在,我军已经侦查到敌军的总部在编号为1的岛屿,而且他们已经没有足够多的能源维系战斗,我军胜利在望.已知在其他k个 ...

  3. BZOJ2286: [Sdoi2011]消耗战(虚树/树形DP)

    Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 5246  Solved: 1978[Submit][Status][Discuss] Descript ...

  4. BZOJ 2286 [Sdoi2011]消耗战 ——虚树

    虚树第一题. 大概就是建一颗只与询问有关的更小的新树,然后在虚树上DP #include <map> #include <ctime> #include <cmath&g ...

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

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

  6. 【BZOJ-2286】消耗战 虚树 + 树形DP

    2286: [Sdoi2011消耗战 Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 2120  Solved: 752[Submit][Status] ...

  7. bzoj 2286: [Sdoi2011]消耗战 虚树+树dp

    2286: [Sdoi2011]消耗战 Time Limit: 20 Sec  Memory Limit: 512 MB[Submit][Status][Discuss] Description 在一 ...

  8. [SDOI2011]消耗战(虚树+树形动规)

    虚树dp 虚树的主要思想: 不遍历没用的的节点以及没用的子树,从而使复杂度降低到\(\sum\limits k\)(k为询问的节点的总数). 所以怎么办: 只把询问节点和其LCA放入询问的数组中. 1 ...

  9. P2495 [SDOI2011]消耗战 虚树

    这是我做的第一道虚树题啊,赶脚不错.其实虚树也没什么奇怪的,就是每棵树给你一些点,让你多次查询,但是我不想每次都O(n),所以我们每次针对给的点建一棵虚树,只包含这些点和lca,然后在这棵虚树上进行树 ...

随机推荐

  1. MongoDB最简单的入门教程之二 使用nodejs访问MongoDB

    在前一篇教程 MongoDB最简单的入门教程之一 环境搭建 里,我们已经完成了MongoDB的环境搭建. 在localhost:27017的服务器上,在数据库admin下面创建了一个名为person的 ...

  2. EXCEL Skills Commonly Used

    1. 判断某一列中的数据是否在另一列中 http://jingyan.baidu.com/article/358570f67fd4b0ce4724fc29.html 2. 快速删除excel中的空格( ...

  3. oracle补丁类型

    名称 说明 Release ¤ 标准产品发布.如Oracle Database 10g Release 2的第一个发行版本为10.2.0.1,可以在OTN.edelivery等站点上公开下载 Patc ...

  4. 指针-AC自动机

    大家都不喜欢指针,但是这个AC自动机仿佛不用不行…… 先引用我最喜欢的话:“AC自动机,不是自动AC的机器.” 如果写不好还可能一直WA AC自动机是KMP与Trie树的完美结合,适用于多字符串匹配, ...

  5. Swift学习——流程控制

    1.for in循环 (1)简单使用: for-in和范围运算符 for i in 1...3 { println(i) } (2)如果在循环中用不到i,可用_代替 for _ in 1...3 { ...

  6. Visual Studio中Radio Button组绑定变量方法(DDX_Radio方法)

    需求描述:Visual Studio 创建的界面程序中又许多 Radio Button,希望这些所有的Radio Button统一绑定到一个变量上,这个变量一旦改变,Radio Button的选中状态 ...

  7. 爬虫学习之第一次获取网页内容及BeautifulSoup处理

    from urllib.request import urlopen from urllib.request import HTTPError from bs4 import BeautifulSou ...

  8. ideal取消按下两次shift弹出搜索框 修改idea,webstrom,phpstrom 快捷键double shift 弹出search everywhere

    因为经常需要在中英文之间切换,所以时常使用shift键,一不小心就把这个Searchwhere 对话框调出来了,很是麻烦. 因此痛定思痛, 我决定将这个按两下shift键就弹出搜索框的快捷键禁用了! ...

  9. Hibernate5.x版本HQL限定查询 Legacy-style query parameters (`?`) are no longer supported

    在此版本的限定查询和4.0版本的限定查询: 如果查询语句是: String hql = "select u from User u where u.gender = ?"; 会出现 ...

  10. Hibernate初始化环境的基本封装

    public class HibernateUtils { private static SessionFactory sf; static{ sf = new Configuration().con ...