BZOJ5329: [SDOI2018]战略游戏——题解
https://www.lydsy.com/JudgeOnline/problem.php?id=5329
https://www.luogu.org/problemnew/show/P4606
省选临近,放飞自我的小Q无心刷题,于是怂恿小C和他一起颓废,玩起了一款战略游戏。这款战略游戏的地图由n个城市以及m条连接这些城市的双向道路构成,并且从任意一个城市出发总能沿着道路走到任意其他城市。现在小C已经占领了其中至少两个城市,小Q可以摧毁一个小C没占领的城市,同时摧毁所有连接这个城市的道路。只要在摧毁这个城市之后能够找到某两个小C占领的城市u和v,使得从u出发沿着道路无论如何都不能走到v,那么小Q就能赢下这一局游戏。小Q和小C一共进行了q局游戏,每一局游戏会给出小C占领的城市集合S,你需要帮小Q数出有多少个城市在他摧毁之后能够让他赢下这一局游戏。
圆方树很好的板子题,以及最开始我题看错了以为是最少多少步才能赢emm…
看到炸点想到tarjan点双缩点,然后套上圆方树。
然后对于询问的点集发现很小,于是套上虚树。
然后任意两个关键点之间的赢法取决于这两个关键点之间有多少圆点,话句话讲,答案就是虚树所有路径在原树上的圆点个数和。
码码码就AC了。
PS:注意虚树的根到原树的根这段路程的圆点不要统计!WA在这里。
(以及强烈吐槽对于tarjan压栈压的是点的同学你们这样做是不对的!)
#include<cmath>
#include<queue>
#include<stack>
#include<cstdio>
#include<cctype>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
typedef double dl;
const int N=2e5+;
const int B=;
const int M=N*;
inline int read(){
int X=,w=;char ch=;
while(!isdigit(ch)){w|=ch=='-';ch=getchar();}
while(isdigit(ch))X=(X<<)+(X<<)+(ch^),ch=getchar();
return w?-X:X;
}
struct node{
int u[M],v[M],nxt[M];
int cnt,head[N];
void init(){
cnt=;
memset(head,,sizeof(head));
}
void add(int U,int V){
u[++cnt]=U;v[cnt]=V;nxt[cnt]=head[U];head[U]=cnt;
}
}e,g;
int n,m;
int dfn[N],low[N],to[N],t,l;
stack<int>q;
void tarjan(int u,int f){
dfn[u]=low[u]=++t;
for(int i=g.head[u];i;i=g.nxt[i]){
int v=g.v[i];
if(!dfn[v]){
q.push(i);
tarjan(v,u);
low[u]=min(low[u],low[v]);
if(low[v]>=dfn[u]){
int num;l++;
do{
num=q.top();q.pop();
int uu=g.u[num],vv=g.v[num];
if(to[uu]!=l){
to[uu]=l;
e.add(uu,l+n);e.add(l+n,uu);
}
if(to[vv]!=l){
to[vv]=l;
e.add(vv,l+n);e.add(l+n,vv);
}
}while(num!=i);
}
}else if(low[u]>dfn[v]&&f!=v){
q.push(i);
low[u]=dfn[v];
}
}
} int anc[N][B+],dep[N],pos[N],len[N],tot;
void dfs(int u,int f){
pos[u]=++tot;
dep[u]=dep[f]+;
len[u]=len[f]+(u<=n);
anc[u][]=f;
for(int i=;i<=B;i++)
anc[u][i]=anc[anc[u][i-]][i-];
for(int i=e.head[u];i;i=e.nxt[i]){
int v=e.v[i];
if(v!=anc[u][])dfs(v,u);
}
}
inline int LCA(int i,int j){
if(dep[i]<dep[j])swap(i,j);
for(int k=B;k>=;--k)
if(dep[anc[i][k]]>=dep[j])i=anc[i][k];
if(i==j)return i;
for(int k=B;k>=;--k)
if(anc[i][k]!=anc[j][k])
i=anc[i][k],j=anc[j][k];
return anc[i][];
} int aux[N],stk[N],fa_aux[N],top,num;
bool cmp(int a,int b){return pos[a]<pos[b];}
int build(int t){
sort(aux+,aux+t+,cmp);
num=t;stk[top=]=;
for(int i=;i<=t;i++){
int u=aux[i];
if(!top)fa_aux[u]=,stk[++top]=u;
else{
int lca=LCA(u,stk[top]);
while(dep[stk[top]]>dep[lca]){
if(dep[stk[top-]]<=dep[lca])
fa_aux[stk[top]]=lca;
top--;
}
if(stk[top]!=lca){
fa_aux[lca]=stk[top];
stk[++top]=lca;
aux[++num]=lca;
}
fa_aux[u]=lca;
stk[++top]=u;
}
}
sort(aux+,aux+num+,cmp);
}
int solve(){
int ans=;
for(int i=num;i>;i--){
int u=aux[i],v=fa_aux[u];
ans+=len[u]-len[v];
}
ans+=aux[]<=n;
return ans;
}
inline void init(){
t=l=tot=;
e.init();g.init();
memset(to,,sizeof(to));
memset(dfn,,sizeof(dfn));
}
int main(){
int T=read();
while(T--){
init();
n=read(),m=read();
for(int i=;i<=m;i++){
int u=read(),v=read();
g.add(u,v);g.add(v,u);
}
for(int i=;i<=n;i++)
if(!dfn[i])tarjan(i,);
dfs(,);
int q=read();
while(q--){
int t=read();
for(int i=;i<=t;i++)aux[i]=read();
build(t);
printf("%d\n",solve()-t);
}
}
return ;
}
+++++++++++++++++++++++++++++++++++++++++++
+本文作者:luyouqi233。 +
+欢迎访问我的博客:http://www.cnblogs.com/luyouqi233/+
+++++++++++++++++++++++++++++++++++++++++++
BZOJ5329: [SDOI2018]战略游戏——题解的更多相关文章
- BZOJ5329:[SDOI2018]战略游戏(圆方树,虚树)
Description 省选临近,放飞自我的小Q无心刷题,于是怂恿小C和他一起颓废,玩起了一款战略游戏. 这款战略游戏的地图由n个城市以及m条连接这些城市的双向道路构成,并且从任意一个城市出发总能沿着 ...
- [BZOJ5329][SDOI2018]战略游戏
bzoj luogu Description 省选临近,放飞自我的小Q无心刷题,于是怂恿小C和他一起颓废,玩起了一款战略游戏. 这款战略游戏的地图由n个城市以及m条连接这些城市的双向道路构成,并且从任 ...
- [bzoj5329] P4606 [SDOI2018]战略游戏
P4606 [SDOI2018]战略游戏:广义圆方树 其实会了圆方树就不难,达不到黑,最多算个紫 那个转换到圆方树上以后的处理方法,画画图就能看出来,所以做图论题一定要多画图,并把图画清楚点啊!! 但 ...
- [SDOI2018]战略游戏 圆方树,树链剖分
[SDOI2018]战略游戏 这题是道路相遇(题解)的升级版,询问的两个点变成了\(S\)个点. LG传送门 还是先建出圆方树,考虑对于询问的\(S\)个点,答案就是圆方树上能包含这些点的最小连通块中 ...
- bzoj5315/luoguP4517 [SDOI2018]战略游戏(圆方树,虚树)
bzoj5315/luoguP4517 [SDOI2018]战略游戏(圆方树,虚树) bzoj Luogu 题目描述略(太长了) 题解时间 切掉一个点,连通性变化. 上圆方树. $ \sum |S| ...
- bzoj 5329: [Sdoi2018]战略游戏
Description 省选临近,放飞自我的小Q无心刷题,于是怂恿小C和他一起颓废,玩起了一款战略游戏. 这款战略游戏的地图由n个城市以及m条连接这些城市的双向道路构成,并且从任意一个城市出发总能沿着 ...
- luogu P4606 [SDOI2018]战略游戏
LINK:战略游戏 一道很有价值的题目.这道题 一张无向联通图 每次询问给出K个关键点 问摧毁图中哪个点可以使得这K个关键的两两之间有一对不能联通 去掉的这个点不能是关键点 求方案数. 可以发现 当K ...
- 【题解】SDOI2018战略游戏
被CNST的大小卡了好久.一定要开到18呀…… 首先,遇到这种带各种各样环的图先考虑是不是可以建立圆方树,在圆方树上求出答案.然后转化为圆方树之后,我们就将图转化到了树上.答案非常的明显:只要一个圆点 ...
- 洛谷P4606 [SDOI2018]战略游戏 【圆方树 + 虚树】
题目链接 洛谷P4606 双倍经验:弱化版 题解 两点之间必经的点就是圆方树上两点之间的圆点 所以只需建出圆方树 每次询问建出虚树,统计一下虚树边上有多少圆点即可 还要讨论一下经不经过根\(1\)的情 ...
随机推荐
- “地表最贵iPhone”到货,iPhone XS 系列手机等你来测!
WeTest 导读 9月13日,苹果正式发布了全新的 iPhone XS 系列智能手机,备受瞩目的iPhone家族新成员具体又是怎样的呢? 关于iPhone XS系列手机的那些新亮点 大屏.双 ...
- 低于0.01%的极致Crash率是怎么做到的?
WeTest 导读 看似系统Bug的Crash 99%都不是系统问题!本文将与你一起探索Crash分析的科学方法. 在移动互联网闯荡多年的iOS手机管家,经过不断迭代创新,已经涵盖了隐私(加密相册). ...
- 【view】 视图组件说明
view 是视图容器,可用于包裹其它组件或文本内容. 原型: <view hover-class="[String]" hover-stop-propagation=&quo ...
- leetcode个人题解——#11 Container with most water
class Solution { public: int maxArea(vector<int>& height) { ; ; ; while(l < r) { int h ...
- 面试中要注意的 3 个 JavaScript 问题
JavaScript 是 所有现代浏览器 的官方语言.因此,各种语言的开发者面试中都会遇到 JavaScript 问题. 本文不讲最新的 JavaScript 库,通用开发实践,或任何新的 ES6 函 ...
- 4-2:实现cp命令
#include <stdio.h> #include <sys/stat.h> #include <fcntl.h> #include <unistd.h& ...
- 第四课——MFC应用程序框架
一.MFC应用程序类型 上篇文章的彩蛋:可通过使用MFC应用程序向导(MFC AppWizard)的功能来创建所需要的应用程序,这意味着不需要输入任何代码.MFC除了应用程序向导,还对应用程序项目有着 ...
- 安装Tensorflow过程pip安装报错:is not a supported wheel on this platform
安装Tensorflow过程pip安装报错:is not a supported wheel on this platform 通过pip安装wheel镜像时,安装指令为: pip install - ...
- iOS- Swift实现UITableView的常见操作
1.前言 Swift在这就不多介绍了,想必大家都已皆知. 离Swift面世也过了有一个多月的时间. 在闲暇时间我用Swift实现了UITableView的一些常见操作. 基本都是可以用上的,今天在 ...
- TCP系列29—窗口管理&流控—3、Nagle算法
一.Nagle算法概述 之前我们介绍过,有一些交互式应用会传递大量的小包(称呼为tinygrams),这些小包的负载可能只有几个bytes,但是TCP和IP的基本头就有40bytes,如果大量传递这种 ...