【题解】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 = 1, head[maxn], to[maxn * 2], last[maxn * 2];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 = 1; memset(head, 0, sizeof(head));} }E1, E2, E3;int read() {int x = 0, k = 1;char c;c = getchar();while(c < '0' || c > '9') { if(c == '-') k = -1; c = getchar(); }while(c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar();return x * k; }void Tarjan(int u) {dfn[u] = low[u] = ++ timer; S[++ S[0]] = 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 = 0;do{x = S[S[0] --]; E2.add(tot, x);}while(x != v);}}else low[u] = min(low[u], dfn[v]);} }void dfs(int u, int fa) {dis[u] = 0, dep[u] = 0;gra[u][0] = fa, dfn[u] = ++ timer, dep[u] = dep[fa] + 1; if(u <= n) dis[u] += 1; dis[u] += dis[fa];for(int i = 1; i < CNST; i ++) gra[u][i] = gra[gra[u][i - 1]][i - 1];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 - 1; ~i; i --) if(dep[gra[x][i]] >= dep[y]) x = gra[x][i];for(int i = CNST - 1; ~i; i --)if(gra[x][i] != gra[y][i]) x = gra[x][i], y = gra[y][i];return x == y ? x : gra[x][0]; }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] = 0; }void Work() {E3.cnp = 1; K = read(), tot = 1, S[1] = 1, S[0] = 1;for(int i = 1; i <= K; i ++) a[i] = read();sort(a + 1, a + 1 + K, cmp);int L = a[1];for(int i = 1; i <= K; i ++){int lca = LCA(S[S[0]], a[i]);L = LCA(L, a[i]);while(23333){if(dep[lca] >= dep[S[S[0] - 1]]){E3.add(S[S[0]], lca); S[0] --;if(lca != S[S[0]]) S[++ S[0]] = lca;break;}if(S[0]) E3.add(S[S[0]], S[S[0] - 1]), S[0] --;}S[++ S[0]] = a[i];}while(S[0] > 1) E3.add(S[S[0]], S[S[0] - 1]), S[0] --;ans = 0; DP(1, 0);if(L > n) printf("%d\n", ans - dis[L] + 1 - K);else printf("%d\n", ans - dis[L] + 2 - K); }void init() {E1.Clear(), E2.Clear(), timer = 0;memset(gra, 0, sizeof(gra)); }int main() {scanf("%d", &T);while(T --){init();tot = n = read(), m = read();for(int i = 1; i <= n; i ++) dfn[i] = low[i] = 0;for(int i = 1; i <= m; i ++){int u = read(), v = read();E1.add(u, v);}S[0] = 0, Tarjan(1); int Q = read();timer = 0; dfs(1, 0);for(int i = 1; i <= Q; i ++) Work();}return 0; }
转载于:https://www.cnblogs.com/twilight-sx/p/9240537.html
【题解】SDOI2018战略游戏相关推荐
- LuoguP4606 [SDOI2018]战略游戏
LuoguP4606 [SDOI2018]战略游戏 题目描述 题目描述 省选临近,放飞自我的小 QQ 无心刷题,于是怂恿小 CC 和他一起颓废,玩起了一款战略游戏. 这款战略游戏的地图由 nn 个城市 ...
- [BZOJ5329][Sdoi2018]战略游戏 圆方树+虚树
5329: [Sdoi2018]战略游戏 Time Limit: 30 Sec Memory Limit: 512 MB Submit: 174 Solved: 109 [Submit][Stat ...
- BZOJ5329: [SDOI2018]战略游戏——题解
https://www.lydsy.com/JudgeOnline/problem.php?id=5329 https://www.luogu.org/problemnew/show/P4606 省选 ...
- [SDOI2018]战略游戏
题目描述 省选临近,放飞自我的小Q无心刷题,于是怂恿小C和他一起颓废,玩起了一款战略游戏. 这款战略游戏的地图由n个城市以及m条连接这些城市的双向道路构成,并且从任意一个城市出发总能沿着道路走到 任意 ...
- BZOJ5329:[SDOI2018]战略游戏(圆方树,虚树)
Description 省选临近,放飞自我的小Q无心刷题,于是怂恿小C和他一起颓废,玩起了一款战略游戏. 这款战略游戏的地图由n个城市以及m条连接这些城市的双向道路构成,并且从任意一个城市出发总能沿着 ...
- [BZOJ5329][SDOI2018]战略游戏
bzoj luogu Description 省选临近,放飞自我的小Q无心刷题,于是怂恿小C和他一起颓废,玩起了一款战略游戏. 这款战略游戏的地图由n个城市以及m条连接这些城市的双向道路构成,并且从任 ...
- Luogu4606 SDOI2018 战略游戏 圆方树、虚树、链并
传送门 弱化版 考虑到去掉一个点使得存在两个点不连通的形式类似割点,不难想到建立圆方树.那么在圆方树上对于给出的关键点建立虚树之后,我们需要求的就是虚树路径上所有圆点的数量减去关键点的数量. 因为没有 ...
- P4606 [SDOI2018]战略游戏
[题意] 给出一个无向图,q次询问,每次给定一个点集s代表占领点,问有多少个未被占领的点可以作为点集s中两个点u,v的割点 [分析] 首先,先建立圆方树,问题转化为能包含 给定点集 的最小连通块的 圆 ...
- [SDOI2018]战略游戏 圆方树+虚树
Description 给T组数据. 每组数据给你一个n个点的无向图,保证图联通,给q个询问. 每个询问给k个节点,问每一次询问中,求有多少个点在断掉他之后可以使图中两个点不连通. Sample In ...
最新文章
- What is 软件工程
- 第二章 搜索 【未完结】
- 利用zookeeper实现发布订阅模式
- OpenGL EnvironmentMapping环境映射的实例
- FPGA学习之路—应用程序—原码二位乘法器及Verilog代码分析
- Java 关键字 transient
- 多个php 链接数据库,ThinkPHP实现多数据库连接的解决方法
- matlab案例_基于matlab和frost平台的cassie案例足式机器人运动学和动力学计算实现过程...
- Android Studio Button背景颜色无法修改
- opencv-4.5.3 + opencv_contrib-4.5.3 + vtk-9.0.3编译(全流程)
- 3.11 随机初始化
- SAP License:ERP实施关键问题
- Transformations on DStreams之updateStateByKey 的使用和状态累加
- 自学python考哪些证书-Python自学难吗?有哪些课程内容?
- mysql数据库中实现内连接、左连接、右连接
- 用火箭送快递?淘宝宣布联合蓝箭航天起启动“宝箭”计划...
- latex 打出罗马数字
- Surrogate mother是代孕妈妈,那么,Surrogate parent呢?
- 【协议】NVMe over RoCE 初探 SATA接口(AHCI协议)、PCIe 接口(NVMe 协议)
- 关于Vivado综合选项——Out of context per IP和Gobal
热门文章
- 计算机打音乐光辉岁月,光辉岁月(完美版)
- 莫队--2038: [2009国家集训队]小Z的袜子(hose)
- 谢希仁计算机网络第七版 以太网单播和多播MAC地址范围[纠错]
- 基类与派生类的类型转换
- 最长反链(bzoj 1143: [CTSC2008]祭祀river)
- 2017CCPC哈尔滨 D:X-Men
- Matlab 小波变换dwt和wavedec
- Histogram Normalization 图像直方图归一化
- 自定义数组名做参数(传指针教学)
- clickhouse 部署+介绍