【题解】SDOI2018战略游戏
被CNST的大小卡了好久。一定要开到18呀……
首先,遇到这种带各种各样环的图先考虑是不是可以建立圆方树,在圆方树上求出答案。然后转化为圆方树之后,我们就将图转化到了树上。答案非常的明显:只要一个圆点位于一个节点到另一个节点的路径上,它就是一个可以选择的答案点。
又观察到数据范围中给出的总和 <= & 多组询问的模式,立马联想到建立虚树。建立出了虚树,我们发现这棵虚树有一个非常妙妙的性质:所有的叶子节点均为指定点。这样的话,在这棵虚树上所有的点(从叶子到根的路径上的点,包括没有建出来的点)均为合法的答案。不过要注意到因为我们自动建立出了1点为根节点,所以要防止1没有被选择,要减去这一段非法的点数。
// luogu-judger-enable-o2
#include <bits/stdc++.h>
using namespace std;
#define maxn 200000
#define CNST 19
int n, m, K, tot, T;
int timer, dfn[maxn], low[maxn];
int dep[maxn], dis[maxn], gra[maxn][CNST];
int ans, S[maxn], a[maxn];
bool vis[maxn]; struct edge
{
int cnp = , head[maxn], to[maxn * ], last[maxn * ];
void add(int u, int v)
{
if(u == v) return;
to[cnp] = v, last[cnp] = head[u], head[u] = cnp ++;
to[cnp] = u, last[cnp] = head[v], head[v] = cnp ++;
}
void Clear()
{
cnp = ; memset(head, , sizeof(head));
}
}E1, E2, E3; int read()
{
int x = , k = ;
char c;
c = getchar();
while(c < '' || c > '') { if(c == '-') k = -; c = getchar(); }
while(c >= '' && c <= '') x = x * + c - '', c = getchar();
return x * k;
} void Tarjan(int u)
{
dfn[u] = low[u] = ++ timer; S[++ S[]] = u;
for(int i = E1.head[u]; i; i = E1.last[i])
{
int v = E1.to[i];
if(!dfn[v])
{
Tarjan(v); low[u] = min(low[u], low[v]);
if(low[v] >= dfn[u])
{
E2.add(++ tot, u); int x = ;
do
{
x = S[S[] --]; E2.add(tot, x);
}while(x != v);
}
}
else low[u] = min(low[u], dfn[v]);
}
} void dfs(int u, int fa)
{
dis[u] = , dep[u] = ;
gra[u][] = fa, dfn[u] = ++ timer, dep[u] = dep[fa] + ;
if(u <= n) dis[u] += ; dis[u] += dis[fa];
for(int i = ; i < CNST; i ++) gra[u][i] = gra[gra[u][i - ]][i - ];
for(int i = E2.head[u]; i; i = E2.last[i])
{
int v = E2.to[i];
if(v != fa) dfs(v, u);
}
} int LCA(int x, int y)
{
if(dep[x] < dep[y]) swap(x, y);
for(int i = CNST - ; ~i; i --)
if(dep[gra[x][i]] >= dep[y]) x = gra[x][i];
for(int i = CNST - ; ~i; i --)
if(gra[x][i] != gra[y][i])
x = gra[x][i], y = gra[y][i];
return x == y ? x : gra[x][];
} bool cmp(int a, int b)
{
return dfn[a] < dfn[b];
} void DP(int u, int fa)
{
for(int i = E3.head[u]; i; i = E3.last[i])
{
int v = E3.to[i];
if(v == fa) continue;
DP(v, u); ans += dis[v] - dis[u];
}
E3.head[u] = ;
} void Work()
{
E3.cnp = ;
K = read(), tot = , S[] = , S[] = ;
for(int i = ; i <= K; i ++) a[i] = read();
sort(a + , a + + K, cmp);
int L = a[];
for(int i = ; i <= K; i ++)
{
int lca = LCA(S[S[]], a[i]);
L = LCA(L, a[i]);
while()
{
if(dep[lca] >= dep[S[S[] - ]])
{
E3.add(S[S[]], lca); S[] --;
if(lca != S[S[]]) S[++ S[]] = lca;
break;
}
if(S[]) E3.add(S[S[]], S[S[] - ]), S[] --;
}
S[++ S[]] = a[i];
}
while(S[] > ) E3.add(S[S[]], S[S[] - ]), S[] --;
ans = ; DP(, );
if(L > n) printf("%d\n", ans - dis[L] + - K);
else printf("%d\n", ans - dis[L] + - K);
} void init()
{
E1.Clear(), E2.Clear(), timer = ;
memset(gra, , sizeof(gra));
} int main()
{
scanf("%d", &T);
while(T --)
{
init();
tot = n = read(), m = read();
for(int i = ; i <= n; i ++) dfn[i] = low[i] = ;
for(int i = ; i <= m; i ++)
{
int u = read(), v = read();
E1.add(u, v);
}
S[] = , Tarjan();
int Q = read();
timer = ; dfs(, );
for(int i = ; i <= Q; i ++) Work();
}
return ;
}
【题解】SDOI2018战略游戏的更多相关文章
- [SDOI2018]战略游戏 圆方树,树链剖分
[SDOI2018]战略游戏 这题是道路相遇(题解)的升级版,询问的两个点变成了\(S\)个点. LG传送门 还是先建出圆方树,考虑对于询问的\(S\)个点,答案就是圆方树上能包含这些点的最小连通块中 ...
- bzoj5315/luoguP4517 [SDOI2018]战略游戏(圆方树,虚树)
bzoj5315/luoguP4517 [SDOI2018]战略游戏(圆方树,虚树) bzoj Luogu 题目描述略(太长了) 题解时间 切掉一个点,连通性变化. 上圆方树. $ \sum |S| ...
- [bzoj5329] P4606 [SDOI2018]战略游戏
P4606 [SDOI2018]战略游戏:广义圆方树 其实会了圆方树就不难,达不到黑,最多算个紫 那个转换到圆方树上以后的处理方法,画画图就能看出来,所以做图论题一定要多画图,并把图画清楚点啊!! 但 ...
- BZOJ5329: [SDOI2018]战略游戏——题解
https://www.lydsy.com/JudgeOnline/problem.php?id=5329 https://www.luogu.org/problemnew/show/P4606 省选 ...
- BZOJ5329:[SDOI2018]战略游戏(圆方树,虚树)
Description 省选临近,放飞自我的小Q无心刷题,于是怂恿小C和他一起颓废,玩起了一款战略游戏. 这款战略游戏的地图由n个城市以及m条连接这些城市的双向道路构成,并且从任意一个城市出发总能沿着 ...
- [BZOJ5329][SDOI2018]战略游戏
bzoj luogu Description 省选临近,放飞自我的小Q无心刷题,于是怂恿小C和他一起颓废,玩起了一款战略游戏. 这款战略游戏的地图由n个城市以及m条连接这些城市的双向道路构成,并且从任 ...
- bzoj 5329: [Sdoi2018]战略游戏
Description 省选临近,放飞自我的小Q无心刷题,于是怂恿小C和他一起颓废,玩起了一款战略游戏. 这款战略游戏的地图由n个城市以及m条连接这些城市的双向道路构成,并且从任意一个城市出发总能沿着 ...
- luogu P4606 [SDOI2018]战略游戏
LINK:战略游戏 一道很有价值的题目.这道题 一张无向联通图 每次询问给出K个关键点 问摧毁图中哪个点可以使得这K个关键的两两之间有一对不能联通 去掉的这个点不能是关键点 求方案数. 可以发现 当K ...
- 洛谷P4606 [SDOI2018]战略游戏 【圆方树 + 虚树】
题目链接 洛谷P4606 双倍经验:弱化版 题解 两点之间必经的点就是圆方树上两点之间的圆点 所以只需建出圆方树 每次询问建出虚树,统计一下虚树边上有多少圆点即可 还要讨论一下经不经过根\(1\)的情 ...
随机推荐
- 【路由和交换之H3C自导自演】
H3C配置自导自演 显示和维护及恢复 1:display display history-command :查看历史命令记录 display diagnostic-information :查看 ...
- CodeTimer 代码性能计数器
收集整理老赵 的”CodeTimer“. 用于测试代码性能.详见可参考 老赵原文 代码如下: using System; using System.Diagnostics; using System. ...
- com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Unknown column
com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Unknown column …… 出现这个异常的很大可能性是 数据库是没有问题的 ...
- 46.VUE学习之--组件之使用动态组件灵活设置页面布局
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- hive-show-partitions
展示分区命令 show partitions show partitions 可以展示这个表格之下的所有分区信息.这个命令常常用在使用SQL语句操作数据之前.举个简单的例子,如果我们想要根据uid融合 ...
- 在linux使用锐捷客户端上网(华中科技大学)
第一步:下载锐捷客户端linux版本,下载网址为http://ncc.hust.edu.cn/cyxz/rzkhd.htm 第二步:解压该包,进入目录 #unzip RG_Supplicant_For ...
- 初步学习pg_control文件之四
接前文,初步学习pg_control文件之三 继续分析 何时出现 DB_SHUTDOWNING状态: 在正常的shutdown的时候,需要进行checkpoint,所以就在此处,设置pg_contr ...
- 安装和配置Sentry(收录)
安装和配置Sentry 本文主要记录安装和配置Sentry的过程,关于Sentry的介绍,请参考 Apache Sentry架构介绍 . 1. 环境说明 系统环境: 操作系统:CentOs 6.6 H ...
- AWS安装CDH5.3-CentOS6.4中关键操作步骤
1.在AWS masternode 上下载cloudera-manager-installer.bin安装包 [root@ip-172-21-42-114 ~]# wget http://archiv ...
- android开源项目之OTTO事件总线(一)
Otto是由Square发布的一个着重于Android支持的基于Guava的强大的事件总线,在对应用程序不同部分进行解耦之后,仍然允许它们进行有效的沟通. 开源项目地址:https://github. ...