【BZOJ3991】寻宝游戏(动态规划)

题面

BZOJ

题解

很明显,从任意一个有宝藏的点开始,每次走到相邻的\(dfs\)的节点就行了。

证明?

类似把一棵树上的关键点全部标记出来

显然是要走一个大环。

这样沿着\(dfs\)序从左至右依次便利是最优的。

用一个\(set\)维护一下就行了

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<set>
#include<map>
#include<vector>
#include<queue>
using namespace std;
#define ll long long
#define RG register
#define MAX 111111
inline int read()
{
RG int x=0,t=1;RG char ch=getchar();
while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();
if(ch=='-')t=-1,ch=getchar();
while(ch<='9'&&ch>='0')x=x*10+ch-48,ch=getchar();
return x*t;
}
int n,m;
struct Line{int v,next;ll w;}e[MAX<<1];
int h[MAX],cnt=1;
inline void Add(int u,int v,ll w){e[cnt]=(Line){v,h[u],w};h[u]=cnt++;}
int dfn[MAX],low[MAX],size[MAX],hson[MAX],top[MAX],dep[MAX],fa[MAX],tim;
ll dis[MAX];
void dfs1(int u,int ff)
{
size[u]=1;fa[u]=ff;dep[u]=dep[ff]+1;
for(int i=h[u];i;i=e[i].next)
{
int v=e[i].v;if(v==ff)continue;
dis[v]=dis[u]+e[i].w;
dfs1(v,u);size[u]+=size[v];
if(size[v]>size[hson[u]])hson[u]=v;
dis[v]=dis[u]+e[i].w;
}
}
void dfs2(int u,int tp)
{
top[u]=tp;dfn[u]=++tim;low[tim]=u;
if(hson[u])dfs2(hson[u],tp);
for(int i=h[u];i;i=e[i].next)
{
int v=e[i].v;
if(v==fa[u]||v==hson[u])continue;
dfs2(v,v);
}
}
int LCA(int u,int v)
{
while(top[u]^top[v])dep[top[u]]<dep[top[v]]?v=fa[top[v]]:u=fa[top[u]];
return dep[u]<dep[v]?u:v;
}
ll Dis(int u,int v){return dis[u]+dis[v]-2*dis[LCA(u,v)];}
bool imp[MAX];
set<int> P;
ll ans=0;
int main()
{
n=read();m=read();
for(int i=1;i<n;++i)
{
int u=read(),v=read(),w=read();
Add(u,v,w);Add(v,u,w);
}
dfs1(1,0);dfs2(1,1);
set<int>::iterator it,it1,it2;
while(m--)
{
int x=read();
if(!imp[x])
{
P.insert(dfn[x]);
it=it1=it2=P.find(dfn[x]);--it1;++it2;
if(it!=P.begin())ans+=Dis(x,low[*it1]);
if(it2!=P.end())ans+=Dis(x,low[*it2]);
if(it!=P.begin()&&it2!=P.end())ans-=Dis(low[*it1],low[*it2]);
}
else
{
it=it1=it2=P.find(dfn[x]);--it1;++it2;
if(it!=P.begin())ans-=Dis(x,low[*it1]);
if(it2!=P.end())ans-=Dis(x,low[*it2]);
if(it!=P.begin()&&it2!=P.end())ans+=Dis(low[*it1],low[*it2]);
P.erase(dfn[x]);
}
imp[x]^=1;
if(P.size()<=1){puts("0");continue;}
it=P.end();--it;
printf("%lld\n",ans+Dis(low[*P.begin()],low[*it]));
}
return 0;
}

【BZOJ3991】寻宝游戏(动态规划)的更多相关文章

  1. BZOJ3991 寻宝游戏 LCA 虚树 SET

    5.26 T1:寻宝游戏 Description 小B最近正在玩一个寻宝游戏,这个游戏的地图中有N个村庄和N-1条道路,并且任何两个村庄之间有且仅有一条路径可达.游戏开始时,玩家可以任意选择一个村庄, ...

  2. [Bzoj3991]寻宝游戏(dfs序+set)

    Description 题目链接 Solution 用set按dfs序维护当前的宝物序列,那么答案为相邻2个点的距离加上头尾2个的距离 Code #include <cstdio> #in ...

  3. [BZOJ3991][SDOI2015]寻宝游戏

    [BZOJ3991][SDOI2015]寻宝游戏 试题描述 小B最近正在玩一个寻宝游戏,这个游戏的地图中有N个村庄和N-1条道路,并且任何两个村庄之间有且仅有一条路径可达.游戏开始时,玩家可以任意选择 ...

  4. 【BZOJ3991】[SDOI2015]寻宝游戏 树链的并+set

    [BZOJ3991][SDOI2015]寻宝游戏 Description 小B最近正在玩一个寻宝游戏,这个游戏的地图中有N个村庄和N-1条道路,并且任何两个村庄之间有且仅有一条路径可达.游戏开始时,玩 ...

  5. [bzoj3991][SDOI2015]寻宝游戏_树链的并_倍增lca_平衡树set

    寻宝游戏 bzoj-3991 SDOI-2015 题目大意:题目链接. 注释:略. 想法:我们发现如果给定了一些点有宝物的话那么答案就是树链的并. 树链的并的求法就是把所有点按照$dfs$序排序然后相 ...

  6. 【BZOJ3991】【SDOI2015】寻宝游戏

    Description ​ 小B最近正在玩一个寻宝游戏,这个游戏的地图中有N个村庄和N-1条道路,并且任何两个村庄之间有且仅有一条路径可达.游戏开始时,玩家可以任意选择一个村庄,瞬间转移到这个村庄,然 ...

  7. CH#56C 异象石 和 BZOJ3991 [SDOI2015]寻宝游戏

    异象石 CH Round #56 - 国庆节欢乐赛 描述 Adera是Microsoft应用商店中的一款解谜游戏. 异象石是进入Adera中异时空的引导物,在Adera的异时空中有一张地图.这张地图上 ...

  8. BZOJ3991:寻宝游戏 (LCA+dfs序+树链求并+set)

    小B最近正在玩一个寻宝游戏,这个游戏的地图中有N个村庄和N-1条道路,并且任何两个村庄之间有且仅有一条路径可达.游戏开始时,玩家可以任意选择一个村庄,瞬间转移到这个村庄,然后可以任意在地图的道路上行走 ...

  9. BZOJ3991 [SDOI2015]寻宝游戏 【dfs序 + lca + STL】

    题目 小B最近正在玩一个寻宝游戏,这个游戏的地图中有N个村庄和N-1条道路,并且任何两个村庄之间有且仅有一条路径可达.游戏开始时,玩家可以任意选择一个村庄,瞬间转移到这个村庄,然后可以任意在地图的道路 ...

随机推荐

  1. AngularJs学习笔记--E2E Testing

    原版地址:http://docs.angularjs.org/guide/dev_guide.e2e-testing 当一个应用的复杂度.大小在增加时,使得依靠人工去测试新特性的可靠性.抓Bug和回归 ...

  2. 软件架构的描述-Architecture Models

    Software architecture involves the high level structure of software system abstraction, by using dec ...

  3. HTML5 classList API

    Having thrust myself into the world of JavaScript and JavaScript Libraries, I've often wondered: Whe ...

  4. 牛客网多校训练第一场 D - Two Graphs

    链接: https://www.nowcoder.com/acm/contest/139/D 题意: 两个无向简单图都有n(1≤n≤8)个顶点,图G1有m1条边,图G2有m2条边,问G2有多少个子图与 ...

  5. 【[JLOI2011]飞行路线】

    据说这是分层图最短路的板子题 但其实就是一个\(dij\)多带了一维状态 我们看到\(k\)很小所以显然我们可以设计一个这样的状态 \(d[v][k]\)表示从起点到点\(v\)免费走了\(k\)条路 ...

  6. HDU 3292 【佩尔方程求解 && 矩阵快速幂】

    任意门:http://acm.hdu.edu.cn/showproblem.php?pid=3292 No more tricks, Mr Nanguo Time Limit: 3000/1000 M ...

  7. mybatis逆向工程mbg

    mbg:mybatis generator=mybatis代码生成器 1.看一下项目结构 其中bean文件,mapper接口文件和mapper.xml文件是代码生成器自动生成的. 使用generato ...

  8. 一个jquery ajax例子

    上次搞了个jquery的AutoComplete效果,感觉很久没写jquery了,趁热打铁,再找点东西练练手.这不,看了一下jquery手册,顺便写了一个小例子,源码我直接贴上来了.   1.新建一个 ...

  9. bit and sbit---c51

    bit和sbit都是C51扩展的变量类型. bit和int char之类的差不多,只不过char=8位, bit=1位而已.都是变量,编译器在编译过程中分配地址.除非你指定,否则这个地址是随机的.这个 ...

  10. Hbuilder连接安卓模拟器,调试app

    本人用的是夜神模拟器,所以下面的命令也是基于夜神的,其他模拟器请自行百度. 1.首先,启动HBuilder和夜神模拟器 然后打开cmd命令提示符 cd进入夜神模拟器bin目录 执行以下命令 nox_a ...