[BZOJ5329][SDOI2018]战略游戏
Description
省选临近,放飞自我的小Q无心刷题,于是怂恿小C和他一起颓废,玩起了一款战略游戏。
这款战略游戏的地图由n个城市以及m条连接这些城市的双向道路构成,并且从任意一个城市出发总能沿着道路走到
任意其他城市。现在小C已经占领了其中至少两个城市,小Q可以摧毁一个小C没占领的城市,同时摧毁所有连接这
个城市的道路。只要在摧毁这个城市之后能够找到某两个小C占领的城市u和v,使得从u出发沿着道路无论如何都不
能走到v,那么小Q就能赢下这一局游戏。
小Q和小C一共进行了q局游戏,每一局游戏会给出小C占领的城市集合S
你需要帮小Q数出有多少个城市在他摧毁之后能够让他赢下这一局游戏。
Input
第一行包含一个正整数\(T\),表示测试数据的组数,
对于每组测试数据,
第一行是两个整数\(n\)和\(m\),表示地图的城市数和道路数,
接下来\(m\)行,每行包含两个整数\(u\)和\(v\)表示第\(u\)个城市和第\(v\)个城市之间有一条道路,同一对城市之间可能有多条道路连接,
第\(m+1\)行是一个整数\(q\),表示游戏的局数,
接下来\(q\)行,每行先给出一个整数\(|S|(2\le |S|\le n)\)
表示小C占领的城市数量,然后给出\(|S|\)个整数\(s1,s2,...s|S|,(1\le s1<s2<s_{|S|}\le n)\),表示小C占领的城市。
\(1\le T \le 10\)
\(2\le n\le 10^5\) 且$ n-1\le m\le 2*10^5$,
\(1\le q\le 10^5\),
对于每组测试数据,有\(\sum |S|\le 2*10^5\)
Output
对于每一局游戏,输出一行,包含一个整数,表示这一局游戏中有多少个城市在小Q摧毁之后能够让他赢下这一局游戏。
Sample Input
2
7 6
1 2
1 3
2 4
2 5
3 6
3 7
3
2 1 2
3 2 3 4
4 4 5 6 7
6 6
1 2
1 3
2 3
1 4
2 5
3 6
4
3 1 2 3
3 1 2 6
3 1 5 6
3 4 5 6
Sample Output
0
1
3
0
1
2
3
sol
这种题基本上可以一眼秒出是圆方树+虚树吧。。。
怎么算答案?
就是用给定的点建出虚树后每条边的长度之和吧。因为切断这棵虚树上的任意一条边都是符合题意的。
所以维护一下路径上有多少个圆点即可。
code
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
int gi(){
int x=0,w=1;char ch=getchar();
while ((ch<'0'||ch>'9')&&ch!='-') ch=getchar();
if (ch=='-') w=0,ch=getchar();
while (ch>='0'&&ch<='9') x=(x<<3)+(x<<1)+ch-'0',ch=getchar();
return w?x:-x;
}
const int N = 4e5+5;
int n,tot,m,Q,dfn[N],low[N],tim,S[N];
int fa[N],dep[N],dis[N],sz[N],son[N],top[N],s[N],q[N];
struct Graph{
int to[N],nxt[N],head[N],cnt;
void init(){
memset(head,0,sizeof(head));
cnt=0;
}
void link(int u,int v){
to[++cnt]=v;nxt[cnt]=head[u];head[u]=cnt;
to[++cnt]=u;nxt[cnt]=head[v];head[v]=cnt;
}
}G1,G2;
void Tarjan(int u){
dfn[u]=low[u]=++tim;S[++S[0]]=u;
for (int e=G1.head[u];e;e=G1.nxt[e]){
int v=G1.to[e];
if (!dfn[v]){
Tarjan(v),low[u]=min(low[u],low[v]);
if (low[v]>=dfn[u]){
G2.link(++tot,u);int x=0;
do{
x=S[S[0]--];G2.link(tot,x);
}while (x!=v);
}
}
else low[u]=min(low[u],dfn[v]);
}
}
void dfs1(int u,int f){
fa[u]=f;dep[u]=dep[f]+1;dis[u]=dis[f]+(u<=n);sz[u]=1;
for (int e=G2.head[u];e;e=G2.nxt[e]){
int v=G2.to[e];if (v==f) continue;
dfs1(v,u);sz[u]+=sz[v];
if (sz[v]>sz[son[u]]) son[u]=v;
}
}
void dfs2(int u,int up){
top[u]=up;dfn[u]=++tim;
if (son[u]) dfs2(son[u],up);
for (int e=G2.head[u];e;e=G2.nxt[e]){
int v=G2.to[e];if (v==fa[u]||v==son[u]) continue;
dfs2(v,v);
}
low[u]=tim;
}
int getlca(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_dfn(int i,int j){return dfn[i]<dfn[j];}
int main(){
int T=gi();while (T--){
tot=n=gi();m=gi();G1.init();G2.init();tim=0;
while (m--){
int u=gi(),v=gi();
G1.link(u,v);
}
memset(dfn,0,sizeof(dfn));
memset(son,0,sizeof(son));
for (int i=1;i<=n;++i) if (!dfn[i]) Tarjan(i);
tim=0,dfs1(1,0),dfs2(1,1);
Q=gi();while (Q--){
int k=gi(),len=k,tp=0,ans=0;
for (int i=1;i<=k;++i) s[i]=gi();
sort(s+1,s+k+1,cmp_dfn);
for (int i=1;i<k;++i) s[++len]=getlca(s[i],s[i+1]);
sort(s+1,s+len+1,cmp_dfn);len=unique(s+1,s+len+1)-s-1;
ans=s[1]<=n;
for (int i=1;i<=len;++i){
while (tp&&low[q[tp]]<dfn[s[i]]) --tp;
if (tp) ans+=dis[s[i]]-dis[q[tp]];
q[++tp]=s[i];
}
printf("%d\n",ans-k);
}
}
return 0;
}
[BZOJ5329][SDOI2018]战略游戏的更多相关文章
- BZOJ5329:[SDOI2018]战略游戏(圆方树,虚树)
Description 省选临近,放飞自我的小Q无心刷题,于是怂恿小C和他一起颓废,玩起了一款战略游戏. 这款战略游戏的地图由n个城市以及m条连接这些城市的双向道路构成,并且从任意一个城市出发总能沿着 ...
- BZOJ5329: [SDOI2018]战略游戏——题解
https://www.lydsy.com/JudgeOnline/problem.php?id=5329 https://www.luogu.org/problemnew/show/P4606 省选 ...
- [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] 战略游戏
Description 给定一张 \(n\) 个点 \(m\) 条边的无向联通图,共有 \(q\) 次操作,每次操作选择一些点作为关键点,询问有多少个点满足删去该点及与其相邻的边后,至少有两个关键点不 ...
- 解题:SDOI2018 战略游戏
题面 先圆方树然后建虚树,答案就是虚树大小.虚树没必要建出来,把原来的点的点权设为1,直接dfs序排序后相邻点求距离加上首尾两个点的距离,最后除以二(画一下可以发现是正反算了两遍),注意还要去掉询问点 ...
随机推荐
- panda 函数-处理空值
今天这里谈的函数,以后进行数据分析的时候会经常用到. import numpy as npimport pandas as pdfrom pandas import DataFrame , Serie ...
- 如何成为 Python 高手
这篇文章主要是对我收集的一些文章的摘要.因为已经有很多比我有才华的人写出了大量关于如何成为优秀Python程序员的好文章. 我的总结主要集中在四个基本题目上:函数式编程,性能,测试,编码规范.如果一个 ...
- selenium的三种等待时间设置
为了提高脚本的稳定性,我们需要在脚本中增加等待时间 第一种:强制等待 Thread.sleep():固定休眠时间设置,Java的Thread类里提供了休眠方法sleep,导入包后就能使用 sleep( ...
- cocos对象池的使用
enemy.js cc.Class({ extends: cc.Component, properties: { enemySpeed: 0, //设置加速度 }, //初始化当前节点的y坐标 ini ...
- 【Error】local variable 'xxx' referenced before assignment
此种错误涉及到变量的作用域,即全局变量和局部变量的操作. 总结如下: 内部函数,不修改全局变量可以访问全局变量 内部函数,修改同名全局变量,则python会认为它是一个局部变量 在内部函数修改同名全局 ...
- 基于Python的XSS测试工具XSStrike使用方法
基于Python的XSS测试工具XSStrike使用方法 简介 XSStrike 是一款用于探测并利用XSS漏洞的脚本 XSStrike目前所提供的产品特性: 对参数进行模糊测试之后构建合适的payl ...
- 登录后保存token值到cookie中
1.引入相应JS <script src="web/js/jquery-1.9.1.min.js"></script> <script src=&qu ...
- pycharm debug
1 debug 的模式,只有在打断点是才能运行. 2 主方法运行的时候 ,可以在下面输入一行 a =1 .方便debug 打完断电的会出现三角头, 运行甲壳虫 3 一步一步运行, F8 , 当 ...
- 【hive】关于浮点数比较的问题
当在hive中写下浮点数(例如:0.2) hive会把浮点数(0.2)存储为double类型 但是系统中并不能精准表示0.2这个浮点数 正确的浮点数表示 float 0.2 —> 0.200 ...
- C# 调用颜色的RGB值_RGB颜色转换十六进制颜色
调用方法: 如:btn_FangTai.BackColor = Color.FromArgb(135, 206, 250); 十六进制颜色查询 颜 色 英文代码 形象描述 十六进制 RGB L ...