bzoj 3991: [SDOI2015]寻宝游戏 虚树 set
目录
题目链接
题解
发现每次答案就是把虚树上的路径*2
接在同一关键点上的点的dfs序是相邻的
那么用set动态维护dfs序列
每次删点加点就好了
代码
#include<set>
#include<cstdio>
#include<algorithm>
#define gc getchar()
#define pc putchar
#define LL long long
inline int read() {
int x = 0,f = 1;
char c = gc;
while(c < '0' || c > '9') c = gc;
while(c <= '9' && c >= '0') x = x * 10 + c - '0',c = gc;
return x * f;
}
void print(LL x) {
if(x < 0) {
pc('-');
x = -x;
}
if(x >= 10) print(x / 10);
pc(x % 10 + '0');
}
const int maxn = 100007;
int n,m;
struct node {
int v,next,w;
} edge[maxn << 1];
int head[maxn],num = 0;
inline void add_edge(int u,int v,int w) {
edge[++ num].v = v; edge[num].w = w; edge[num].next = head[u];head[u] = num;
}
std::set<int>s;
std::set<int> :: iterator it,qi,ho;
int deep[maxn],top[maxn],fa[maxn],son[maxn],siz[maxn];
LL dis[maxn];
void dfs1(int x,int f) {
deep[x] = deep[f] + 1,fa[x] = f;
siz[x] = 1;
for(int i = head[x];i;i = edge[i].next) {
int v = edge[i].v;
if(v != f) {
dis[v] = dis[x] + edge[i].w;
dfs1(v,x);
if(siz[v] > siz[son[x]]) son[x] = v;
siz[x] += siz[v];
}
}
}
int cnt = 0,dfn[maxn],ra[maxn];
void dfs2(int x,int tp) {
top[x] = tp; dfn[x] = ++ cnt;ra[cnt] = x;
if(son[x]) dfs2(son[x],tp);
for(int i = head[x];i;i = edge[i].next) {
int v = edge[i].v;
if(v == fa[x] || v == son[x]) continue;
dfs2(v,v);
}
}
int lca(int x,int y) {
while(top[x] != top[y]) {
if(deep[top[x]] > deep[top[y]]) x = fa[top[x]];
else y = fa[top[y]];
}
return deep[x] > deep[y] ? y : x;
}
LL query(int x) {
it = s.find(dfn[x]);
if(it == s.begin()) {qi = s.end();qi --; }
else {qi = it ;qi --; }
ho = it;ho ++;
if(ho == s.end()) ho = s.begin();
return dis[ra[* ho]] + dis[ra[* it]] * 2 + dis[ra[* qi]] - dis[lca(ra[* ho],ra[* it])] * 2 - dis[lca(ra[* it],ra[* qi])] * 2;
}
bool vis[maxn];
LL work(int x) {
it = s.find(dfn[x]);
if(it == s.begin()) {qi = s.end();qi --; }
else {qi = it; qi --;}
ho = it;ho ++;
if(ho == s.end()) ho = s.begin();
return dis[ra[*ho]] + dis[ra[*qi]] - 2 * dis[lca(ra[*qi],ra[*ho])];
}
int main() {
n = read(),m = read();
for(int u,v,w,i = 1;i < n;++ i) {
u = read(),v = read(),w = read();
add_edge(u,v,w); add_edge(v,u,w);
}
LL ans = 0;
dfs1(1,0);
dfs2(1,1);
for(int i = 1;i <= m;++ i) {
int x = read();
if(vis[x]) {
ans -= query(x);
ans += work(x);
s.erase(dfn[x]),vis[x] = 0;
} else {
vis[x] = 1;
s.insert(dfn[x]);
ans -= work(x);
ans += query(x);
}
printf("%lld\n",ans);
}
return 0;
}
bzoj 3991: [SDOI2015]寻宝游戏 虚树 set的更多相关文章
- BZOJ 3991: [SDOI2015]寻宝游戏 [虚树 树链的并 set]
传送门 题意: $n$个点的树,$m$次变动使得某个点有宝物或没宝物,询问每次变动后集齐所有宝物并返回原点的最小距离 转化成有根树,求树链的并... 两两树链求并就可以,但我们按照$dfs$序来两两求 ...
- 【BZOJ】3991: [SDOI2015]寻宝游戏 虚树+DFS序+set
[题意]给定n个点的带边权树,对于树上存在的若干特殊点,要求任选一个点开始将所有特殊点走遍后返回.现在初始没有特殊点,m次操作每次增加或减少一个特殊点,求每次操作后的总代价.n,m<=10^5. ...
- BZOJ 3991: [SDOI2015]寻宝游戏 树链的并+set
Description 小B最近正在玩一个寻宝游戏,这个游戏的地图中有N个村庄和N-1条道路,并且任何两个村庄之间有且仅有一条路径可达.游戏开始时,玩家可以任意选择一个村庄,瞬间转移到这个村庄,然后可 ...
- bzoj 3991: [SDOI2015]寻宝游戏
Description 小B最近正在玩一个寻宝游戏,这个游戏的地图中有N个村庄和N-1条道路,并且任何两个村庄之间有且仅有一条路径可达.游戏开始时,玩家可以任意选择一个村庄,瞬间转移到这个村庄,然后可 ...
- 树形结构的维护:BZOJ 3991: [SDOI2015]寻宝游戏
Description 小B最近正在玩一个寻宝游戏,这个游戏的地图中有N个村庄和N-1条道路,并且任何两个村庄之间有且仅有一条路径可达.游戏开始时,玩家可以任意选择一个村庄,瞬间转移到这个村庄,然后可 ...
- BZOJ.3991.[SDOI2015]寻宝游戏(思路 set)
题目链接 从哪个点出发最短路径都是一样的(最后都要回来). 脑补一下,最短路应该是按照DFS的顺序,依次访问.回溯遍历所有点,然后再回到起点. 即按DFS序排序后,Ans=dis(p1,p2)+dis ...
- [BZOJ 3991][SDOI2015]寻宝游戏(dfs序)
题面 小B最近正在玩一个寻宝游戏,这个游戏的地图中有N个村庄和N-1条道路,并且任何两个村庄之间有且仅有一条路径可达.游戏开始时,玩家可以任意选择一个村庄,瞬间转移到这个村庄,然后可以任意在地图的道路 ...
- 3991: [SDOI2015]寻宝游戏
3991: [SDOI2015]寻宝游戏 https://www.lydsy.com/JudgeOnline/problem.php?id=3991 分析: 虚树+set. 要求树上许多点之间的路径的 ...
- [bzoj3991][SDOI2015]寻宝游戏_树链的并_倍增lca_平衡树set
寻宝游戏 bzoj-3991 SDOI-2015 题目大意:题目链接. 注释:略. 想法:我们发现如果给定了一些点有宝物的话那么答案就是树链的并. 树链的并的求法就是把所有点按照$dfs$序排序然后相 ...
随机推荐
- Box-Muller 与 ziggurat
1. Ziggurat 算法与 Box-muller 算法的效率比较 2. Box-Muller a. 一般形式 因函数调用较多,速度慢,当u接近0时存在数值稳定性问题 先假设. 用Box-Mulle ...
- Protues常用元器件查找对应表
原理图常用库文件:Miscellaneous Devices.ddbDallas Microprocessor.ddbIntel Databooks.ddbProtel DOS Schematic L ...
- SpringMVC集成MongoDb
(1)pom添加相关依赖 <dependency> <groupId>org.springframework.data</groupId> <artifact ...
- CEdit使用(Edit Control控件)
CEdit使用(Edit Control控件) 编辑框只读 属性 Read Only等于 True,就有了只读效果 密码框 属性 Password 等于 True,就有了密码效果 获取值/赋予值 Up ...
- 关于GTID模式下备份时 --set-gtid-purged=OFF 参数的实验【转】
刚刚听了吴老师是复制章节课程,对于GTID模式下备份数据--set-gtid-purged=OFF 参数有些不理解,于是乎做了实验,加深理解,得出些结论,如有错漏请批评指正! 部分备份: [root@ ...
- python高级编程读书笔记(一)
python高级编程读书笔记(一) python 高级编程读书笔记,记录一下基础和高级用法 python2和python3兼容处理 使用sys模块使程序python2和python3兼容 import ...
- Python3学习笔记17-类与实例
面向对象最重要的概念就是类(Class)和实例(Instance),必须牢记类是抽象的模板,比如Student类 而实例是根据类创建出来的一个个具体的“对象”,每个对象都拥有相同的方法,但各自的数据可 ...
- 用jquery添加新元素很容易,面对jquery append 动态添加的元素事件on 不起作用我们该如何解决呢?
用jquery添加新元素很容易,面对jquery append 动态添加的元素事件on 不起作用我们该如何解决呢?on方法中要先找到原选择器(如例.info),再找到动态添加的选择器(如列.delet ...
- 使用Java类库POI生成简易的Excel报表
使用Java类库POI生成简易的Excel报表 1.需求 1.数据库生成报表需要转义其中字段的信息.比如 1,有效 2.无效等 2.日期格式的自数据需要转义其格式. 3.标题的格式和数据的格式需要分别 ...
- cf220B莫队
用莫队比直接做快了很多.. #include<iostream> #include<cstring> #include<cstdio> #include<cm ...