【BZOJ5329】【SDOI2018】战略游戏(圆方树,虚树)
【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~(1<=u<v<=n)
表示第u个城市和第v个城市之间有一条道路,同一对城市之间可能有多条道路连接,
第m+1是一个整数q,表示游戏的局数,
接下来q行,每行先给出一个整数|S|(2<=|S|<=n)
表示小C占领的城市数量,然后给出|S|个整数s1,s2,...s|S|,(1<=s1<s2<s|S|<=n),表示小C占领的城市。
1<= T<= 10,
2<= n<= 10^5 且 n-1<= m<= 210^5,
1<= q<= 10^5,
对于每组测试数据,有Sigma|S|<= 210^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
题解
首先把一般图构建出圆方树,
考虑若干个点的贡献,
显然是把他们连成一个最小的联通块,然后计算里面的圆点个数。
这样子答案就可以通过构建虚树计算出答案啦。
#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 222222
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 Tot,n,m;
struct Line{int v,next;};
struct Link
{
Line e[MAX<<2];
int h[MAX],cnt;
void init(){memset(h,0,sizeof(h));cnt=0;}
void Add(int u,int v)
{
e[++cnt]=(Line){v,h[u]};h[u]=cnt;
e[++cnt]=(Line){u,h[v]};h[v]=cnt;
}
}G,T;
namespace Graph
{
int dfn[MAX],low[MAX],tim,S[MAX],top;
void init(){memset(dfn,0,sizeof(dfn));memset(low,0,sizeof(low));tim=top=0;}
void Tarjan(int u)
{
dfn[u]=low[u]=++tim;S[++top]=u;
for(int i=G.h[u];i;i=G.e[i].next)
{
int v=G.e[i].v;
if(!dfn[v])
{
Tarjan(v);low[u]=min(low[u],low[v]);
if(low[v]>=dfn[u])
{
T.Add(++Tot,u);int x;
do{x=S[top--];T.Add(Tot,x);}while(v!=x);
}
}
else low[u]=min(low[u],dfn[v]);
}
}
}
namespace RST
{
int dfn[MAX],low[MAX],tim,fa[MAX],dep[MAX],top[MAX],size[MAX],hson[MAX],dis[MAX];
void init(){memset(hson,0,sizeof(hson));tim=0;}
void dfs1(int u,int ff)
{
fa[u]=ff;size[u]=1;dep[u]=dep[ff]+1;dis[u]=dis[ff]+(u<=n);
for(int i=T.h[u];i;i=T.e[i].next)
{
int v=T.e[i].v;if(v==ff)continue;
dfs1(v,u);size[u]+=size[v];
if(size[v]>size[hson[u]])hson[u]=v;
}
}
void dfs2(int u,int tp)
{
top[u]=tp;dfn[u]=++tim;
if(hson[u])dfs2(hson[u],tp);
for(int i=T.h[u];i;i=T.e[i].next)
if(T.e[i].v!=fa[u]&&T.e[i].v!=hson[u])
dfs2(T.e[i].v,T.e[i].v);
low[u]=tim;
}
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;
}
bool cmp(int a,int b){return dfn[a]<dfn[b];}
int p[MAX],S[MAX],K;
void Solve()
{
K=read();int ans=0,len=K;
for(int i=1;i<=K;++i)p[i]=read();
sort(&p[1],&p[K+1],cmp);
for(int i=K;i>1;--i)p[++K]=LCA(p[i],p[i-1]);
sort(&p[1],&p[K+1],cmp);K=unique(&p[1],&p[K+1])-p-1;
ans=p[1]<=n;
for(int i=1,tp=0;i<=K;++i)
{
while(tp&&low[S[tp]]<dfn[p[i]])--tp;
if(tp)ans+=dis[p[i]]-dis[S[tp]];S[++tp]=p[i];
}
printf("%d\n",ans-len);
}
}
int main()
{
int TCase=read();
while(TCase--)
{
Tot=n=read();m=read();G.init();T.init();
for(int i=1;i<=m;++i)G.Add(read(),read());
Graph::init();Graph::Tarjan(1);
RST::init();RST::dfs1(1,0);RST::dfs2(1,1);
int Q=read();
while(Q--)RST::Solve();
}
return 0;
}
【BZOJ5329】【SDOI2018】战略游戏(圆方树,虚树)的更多相关文章
- BZOJ5329:[SDOI2018]战略游戏(圆方树,虚树)
Description 省选临近,放飞自我的小Q无心刷题,于是怂恿小C和他一起颓废,玩起了一款战略游戏. 这款战略游戏的地图由n个城市以及m条连接这些城市的双向道路构成,并且从任意一个城市出发总能沿着 ...
- bzoj5315/luoguP4517 [SDOI2018]战略游戏(圆方树,虚树)
bzoj5315/luoguP4517 [SDOI2018]战略游戏(圆方树,虚树) bzoj Luogu 题目描述略(太长了) 题解时间 切掉一个点,连通性变化. 上圆方树. $ \sum |S| ...
- [SDOI2018]战略游戏 圆方树,树链剖分
[SDOI2018]战略游戏 这题是道路相遇(题解)的升级版,询问的两个点变成了\(S\)个点. LG传送门 还是先建出圆方树,考虑对于询问的\(S\)个点,答案就是圆方树上能包含这些点的最小连通块中 ...
- Luogu4606 SDOI2018 战略游戏 圆方树、虚树、链并
传送门 弱化版 考虑到去掉一个点使得存在两个点不连通的形式类似割点,不难想到建立圆方树.那么在圆方树上对于给出的关键点建立虚树之后,我们需要求的就是虚树路径上所有圆点的数量减去关键点的数量. 因为没有 ...
- BZOJ.5329.[SDOI2018]战略游戏(圆方树 虚树)
题目链接 显然先建圆方树,方点权值为0圆点权值为1,两点间的答案就是路径权值和减去起点终点. 对于询问,显然可以建虚树.但是只需要计算两关键点间路径权值,所以不需要建出虚树.统计DFS序相邻的两关键点 ...
- Luogu P4606 [SDOI2018] 战略游戏 圆方树 虚树
https://www.luogu.org/problemnew/show/P4606 把原来的图的点双联通分量缩点(每个双联通分量建一个点,每个割点再建一个点)(用符合逻辑的方式)建一棵树(我最开始 ...
- [BZOJ5329][SDOI2018]战略游戏
bzoj luogu Description 省选临近,放飞自我的小Q无心刷题,于是怂恿小C和他一起颓废,玩起了一款战略游戏. 这款战略游戏的地图由n个城市以及m条连接这些城市的双向道路构成,并且从任 ...
- 【SDOI2018】战略游戏(同时普及虚树)
先看一道虚树普及题:给你一棵 $n$ 个点的树,$m$ 次询问,每次询问给你 $k$ 个关键点,求把这些点都连起来的路径并的最短长度.$1\le n,m\le 100000,\space 1\le \ ...
- BZOJ5329: [SDOI2018]战略游戏——题解
https://www.lydsy.com/JudgeOnline/problem.php?id=5329 https://www.luogu.org/problemnew/show/P4606 省选 ...
- [SDOI2018]战略游戏(圆方树+虚树)
喜闻乐见的圆方树+虚树 图上不好做,先建出圆方树. 然后答案就是没被选到的且至少有两条边可以走到被选中的点的圆点的数量. 语文不好,但结论画画图即可得出. 然后套路建出虚树. 发现在虚树上DP可以得出 ...
随机推荐
- Git学习系列 (一)
打算花一个半月的时间学完Git.宏观上有更深的认识. 参考: Pro Git(中文版) 一.历史 本地版本控制系统 最原始的做法.复制整个项目目录的方式来保存不同的版本,或许还会改名加上备份时间以示区 ...
- 华天正real210开发板测试-第1篇
1. 网上买的real210二手开发板,今天刚到测试一下 2. 启动方式,不过目前唯一的问题是没有开发资料,然后给原厂发了份邮件要资料,原厂爽快的给了,必须给华天正这服务态度点个赞啊 3. 调到nan ...
- 《绝地求生大逃杀》BE错误怎么办 BE服务未正常运行及安装失败解决方法
<绝地求生大逃杀>BattlEye Launcher是游戏的反作弊程序,也是启动过程中做容易出现错误的,今天小编带来“爆锤吧务”分享的<绝地求生大逃杀>BE服务未正常运行及安装 ...
- 一个小白的测试环境docker化之路
本文来自网易云社区 作者:叶子 学习docker搭建测试环境断断续续也有三个多月了,希望记录一下这个过程.常言道,总结过去,展望未来嘛~文章浅显,还望各位大神路过轻拍. 按照国际惯例,先说一下背景: ...
- Omad群组部署、依赖部署一键解决
本文来自网易云社区 作者:李培斌 前言 基于omad部署平台实现一键部署的实践已有很多成功的经验,杭研QA的技术先锋们也在ks圈里有很多不同的文章去阐述关于这类需求的实现和思路,当然包括我们金融事业部 ...
- 两分钟了解Docker的优势
本文来自网易云社区 我们主要从Docker对业务架构和生产实践的角度来分析. 随着业务规模的逐渐扩大,产品复杂度也随着增加,企业需要解决快速迭代.高可靠和高可用等问题,一个自然的选择是服务化的拆分,把 ...
- Qt PC 安卓 tcp传输文件
废话不多说,如题,上代码 qt PC端 头文件 //网络部分 #include <QTcpSocket> #include <QFile> #include <QFile ...
- Appium(Python)API
1.创建新的会话desired_caps = desired_caps = { 'platformName': 'Android', 'platformVersion': '7.0', 'dev ...
- Objective-C 内存管理和ARC
内存管理 范围: 任何继承了NSObject的对象 对基本数据类型无效 原理: 每个对象内部都保存了一个与之相关联的整数 称为引用计数器 1.计数器的基本操作 当使用alloc new或者copy创建 ...
- Balanced Lineup:线段树:区间最值 / RMQ
不要被线段树这个名字和其长长的代码吓到. D - Balanced Lineup Description For the daily milking, Farmer John's N cows (1 ...