题意:
小B最近正在玩一个寻宝游戏,这个游戏的地图中有N个村庄和N-1条道路,并且任何两个村庄之间有且仅有一条路径可达。游戏开始时,玩家可以任意选择一个村庄,瞬间转移到这个村庄,然后可以任意在地图的道路上行走,若走到某个村庄中有宝物,则视为找到该村庄内的宝物,直到找到所有宝物并返回到最初转移到的村庄为止。小B希望评测一下这个游戏的难度,因此他需要知道玩家找到所有宝物需要行走的最短路程。但是这个游戏中宝物经常变化,有时某个村庄中会突然出现宝物,有时某个村庄内的宝物会突然消失,因此小B需要不断地更新数据,但是小B太懒了,不愿意自己计算,因此他向你求助。为了简化问题,我们认为最开始时所有村庄内均没有宝物
题解:
①有一个比较常见的结论:
从一个点出发,经过指定的k个点再回到原点走的路径的长度是这k个点构成的生成树的边权和的两倍
②这道题如果把有宝藏的点当作特殊点,就相当于维护m棵虚树.
③每次重新建虚树是肯定不行的,每次只会修改一个点,插入和删除这个点一定会伴随着若干条路径的改变,找到这些路径就好了
④画图分析可以知道:
这些路径一定是当前操作的点x和DFS序在它前面的最后一个点L组成的
或者是和DFS序在它后面的第一个点R组成的
⑴如果L存在,那么这条路径就是L→x
⑵如果R存在路径R→x到x也会受到影响
⑶如果L和R同时存在,还要排除L→R的影响
⑷ans还要加上tmp是因为直接加dis会使DFS序最小的点x到DFS序最大的点y这条边x→y只算了一次,要加上另一次
⑤只需要记住每次加点还是删点都会改变若干条路径对答案的贡献,找到这些路径并修改贡献就好了.
⑥因为要每次要插入一个DFS序,找前驱后继,所以用set来维护

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <set>
using namespace std;
typedef long long LL;
const int maxn=100000+10;
struct Node{int to,next,data;
}a[maxn<<1];
int n,m,head[maxn],cnt;
int prt[maxn],deep[maxn],size[maxn],son[maxn];
LL dis[maxn];
int Dfn[maxn],Time,top[maxn],pos[maxn];
bool flag[maxn];
LL ans=0;
set<int>S;
void Init();
void Insert(int,int,int);
void DFS1(int,int,int);
void DFS2(int,int);
int LCA(int,int);
LL Dis(int,int);
void Solve_Insert(int);
void Solve_Delte(int);
int main(){// freopen("in.cpp","r",stdin);
        Init();return 0;
}
void Init(){scanf("%d%d",&n,&m);int x,y,z;for(int i=1;i<n;i++){scanf("%d%d%d",&x,&y,&z);Insert(x,y,z);Insert(y,x,z);}DFS1(1,0,1);DFS2(1,1);S.insert(0);S.insert(n+1);while(m--){scanf("%d",&x);flag[x]=!flag[x];if(flag[x])Solve_Insert(x);else Solve_Delte(x);}
}
void Solve_Insert(int x){int L,R,prt1,prt2;LL tmp=0;S.insert(Dfn[x]);L=*--S.find(Dfn[x]);R=*++S.find(Dfn[x]);if(L>=1)ans+=Dis(pos[L],x);if(R<=n)ans+=Dis(pos[R],x);if(L>=1 && R<=n)ans-=Dis(pos[L],pos[R]);L=*++S.find(0),R=*--S.find(n+1);if(L>=1 && R<=n)tmp=Dis(pos[L],pos[R]);printf("%lld\n",tmp+ans);
}
void Solve_Delte(int x){int L,R,prt1,prt2;LL tmp=0;L=*--S.find(Dfn[x]);R=*++S.find(Dfn[x]);if(L>=1)ans-=Dis(pos[L],x);if(R<=n)ans-=Dis(pos[R],x);if(L>=1 && R<=n)ans+=Dis(pos[L],pos[R]);S.erase(Dfn[x]);L=*++S.find(0),R=*--S.find(n+1);if(L>=1 && R<=n)tmp=Dis(pos[L],pos[R]);printf("%lld\n",tmp+ans);
}
void Insert(int x,int y,int z){a[++cnt].to=y;a[cnt].next=head[x];a[cnt].data=z;head[x]=cnt;
}
#define y a[i].to
void DFS1(int x,int prt,int deep){::deep[x]=deep;::prt[x]=prt;::size[x]=1;for(int i=head[x];i;i=a[i].next){if(y==prt)continue;dis[y]=dis[x]+a[i].data;DFS1(y,x,deep+1);size[x]+=size[y];if(size[y]>size[son[x]])son[x]=y;}
}
void DFS2(int x,int top){::Dfn[x]=++Time;::top[x]=top;::pos[Time]=x;if(son[x])DFS2(son[x],top);for(int i=head[x];i;i=a[i].next){if(y==prt[x] || y==son[x])continue;DFS2(y,y);}
}
#undef y
int LCA(int x,int y){while(top[x]!=top[y]){if(deep[top[x]]<deep[top[y]])swap(x,y);x=prt[top[x]];}if(deep[x]<deep[y])return x;return y;
}
LL Dis(int x,int y){return dis[x]+dis[y]-2*dis[LCA(x,y)];
}

转载于:https://www.cnblogs.com/holy-unicorn/p/9510293.html

HYSBZ 3991 寻宝游戏相关推荐

  1. 【BZOJ 3991】 [SDOI2015]寻宝游戏

    3991: [SDOI2015]寻宝游戏 Time Limit: 40 Sec Memory Limit: 128 MB Submit: 251 Solved: 137 [Submit][Status ...

  2. SDOI2015寻宝游戏 dfs序+set

    SDOI2015寻宝游戏 好像是一道虚树入门题? 虚树???不会不会我弱死了.. Solution: 关键点间的最小路径,就是在保证尽量少走重复路的前提下走出来的一条经过所有关键点的路径. 基于这个思 ...

  3. 河北工业大学c语言寻宝游戏,计算机技术基础(c语言)课程设计寻宝游戏.doc

    计算机技术基础(c语言)课程设计寻宝游戏 计算机技术基础(c语言)课程设计 寻宝游戏 #include #include #include #include #include #define ESC ...

  4. hdu 6289 寻宝游戏

    寻宝游戏 Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 512000/512000 K (Java/Others) Total Sub ...

  5. 寻宝游戏 - 利用iBeacon特性设计的iOS线下寻宝游戏 - 物联网小游戏

    寻宝游戏 - 利用iBeacon特性设计的iOS线下寻宝游戏 作者简介 科科香,程序员 方向:IoT,方案集成,喜好各种新鲜东东 转载请注明出处 iBeacon简介 iBeacon(下面简称Beaco ...

  6. minecraft_使用MCDungeon将地牢,废墟和寻宝游戏添加到您的Minecraft世界中

    minecraft If you've grown tired of exploring the vanilla Minecraft world and the thrill of stumbling ...

  7. 许嵩续约太合音乐集团 携手开启《寻宝游戏》

    7月24日,许嵩<寻宝游戏>发布会暨续约仪式在北京顺利召开.在推出新专辑<寻宝游戏>之际,也宣布续约太合音乐集团,启动未来"无限"可能. 许嵩畅谈新专< ...

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

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

  9. 06:寻宝_第1集:寻宝游戏!

    06:寻宝 Let's kick things off with something a bit unusual: a virtual scavenger hunt. 让我们从一些不寻常的事情开始:虚 ...

  10. BZOJ 3991: [SDOI2015]寻宝游戏

    随便选一个点当做根,跑每个点的深度(为了求LCA)d [ u ] ,和到根节点的距离(为了更新答案) l [ u ] 我们发现,由关键点和他们的LCA构成的虚树(其实就是忽略其他节点),由于还要回到原 ...

最新文章

  1. GNUGK 作为Gatekeeper穿透防火墙和NAT
  2. 算子find_shpe_model参数详解
  3. Does the “LINQ to Objects” provider have built-in performance optimization?
  4. xcode 本地git代码管理
  5. 【BCFTOOLS】按样本拆分VCF文件
  6. html vw自动跳到ie,CSS3动画/关键帧,在IE11问题中使用vw进行转换
  7. vs2013和vs2010的配置
  8. 从能用到好用,GIS信创如何做到行稳致远?
  9. Linux中远程文件的传输
  10. ICCV2021|STMN:双记忆网络提升视频行人ReID性能
  11. python和c 的区别-Python和c语言的主要区别在哪
  12. (三) 初识XMAL
  13. Android 四大组件学习之BroadcastReceiver三
  14. [APK签名] .pk8、.x509.pem转化为.keystore签名
  15. java做抽奖小程序_随机抽奖小程序
  16. 基于单片机的无线病房呼叫系统设计
  17. 最全PR曲线、ROC曲线以及AUC计算公式详解
  18. Pikachu靶场暴力破解通关
  19. Python(1-10章)知识点
  20. 雷电模拟器导入burp证书

热门文章

  1. 收藏 | 绝不能错过的24个顶级Python库
  2. drupal 8 php filter,Drupal 7 与 Drupal 8 的一些变化
  3. 企业上云“行稳致远”,新钛云服“服务+产品”模式升级上云、用云新思维 | 爱分析洞见...
  4. OpenOffice实现word转pdf
  5. 你需要来自TrustedInstaller的权限才能对此文件夹进行更改(已解决)
  6. Scrapy--下载器中间件(Downloader Middleware)
  7. 汽车冬季养护的四个重点
  8. 12306自动抢票软件
  9. Matlab绘制实心圆和实心圆点
  10. 玩游戏计算机丢失msvcp,计算机丢失msvcp,因计算机丢失msvcp140