被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战略游戏相关推荐

  1. LuoguP4606 [SDOI2018]战略游戏

    LuoguP4606 [SDOI2018]战略游戏 题目描述 题目描述 省选临近,放飞自我的小 QQ 无心刷题,于是怂恿小 CC 和他一起颓废,玩起了一款战略游戏. 这款战略游戏的地图由 nn 个城市 ...

  2. [BZOJ5329][Sdoi2018]战略游戏 圆方树+虚树

    5329: [Sdoi2018]战略游戏 Time Limit: 30 Sec  Memory Limit: 512 MB Submit: 174  Solved: 109 [Submit][Stat ...

  3. BZOJ5329: [SDOI2018]战略游戏——题解

    https://www.lydsy.com/JudgeOnline/problem.php?id=5329 https://www.luogu.org/problemnew/show/P4606 省选 ...

  4. [SDOI2018]战略游戏

    题目描述 省选临近,放飞自我的小Q无心刷题,于是怂恿小C和他一起颓废,玩起了一款战略游戏. 这款战略游戏的地图由n个城市以及m条连接这些城市的双向道路构成,并且从任意一个城市出发总能沿着道路走到 任意 ...

  5. BZOJ5329:[SDOI2018]战略游戏(圆方树,虚树)

    Description 省选临近,放飞自我的小Q无心刷题,于是怂恿小C和他一起颓废,玩起了一款战略游戏. 这款战略游戏的地图由n个城市以及m条连接这些城市的双向道路构成,并且从任意一个城市出发总能沿着 ...

  6. [BZOJ5329][SDOI2018]战略游戏

    bzoj luogu Description 省选临近,放飞自我的小Q无心刷题,于是怂恿小C和他一起颓废,玩起了一款战略游戏. 这款战略游戏的地图由n个城市以及m条连接这些城市的双向道路构成,并且从任 ...

  7. Luogu4606 SDOI2018 战略游戏 圆方树、虚树、链并

    传送门 弱化版 考虑到去掉一个点使得存在两个点不连通的形式类似割点,不难想到建立圆方树.那么在圆方树上对于给出的关键点建立虚树之后,我们需要求的就是虚树路径上所有圆点的数量减去关键点的数量. 因为没有 ...

  8. P4606 [SDOI2018]战略游戏

    [题意] 给出一个无向图,q次询问,每次给定一个点集s代表占领点,问有多少个未被占领的点可以作为点集s中两个点u,v的割点 [分析] 首先,先建立圆方树,问题转化为能包含 给定点集 的最小连通块的 圆 ...

  9. [SDOI2018]战略游戏 圆方树+虚树

    Description 给T组数据. 每组数据给你一个n个点的无向图,保证图联通,给q个询问. 每个询问给k个节点,问每一次询问中,求有多少个点在断掉他之后可以使图中两个点不连通. Sample In ...

最新文章

  1. What is 软件工程
  2. 第二章 搜索 【未完结】
  3. 利用zookeeper实现发布订阅模式
  4. OpenGL EnvironmentMapping环境映射的实例
  5. FPGA学习之路—应用程序—原码二位乘法器及Verilog代码分析
  6. Java 关键字 transient
  7. 多个php 链接数据库,ThinkPHP实现多数据库连接的解决方法
  8. matlab案例_基于matlab和frost平台的cassie案例足式机器人运动学和动力学计算实现过程...
  9. Android Studio Button背景颜色无法修改
  10. opencv-4.5.3 + opencv_contrib-4.5.3 + vtk-9.0.3编译(全流程)
  11. 3.11 随机初始化
  12. SAP License:ERP实施关键问题
  13. Transformations on DStreams之updateStateByKey 的使用和状态累加
  14. 自学python考哪些证书-Python自学难吗?有哪些课程内容?
  15. mysql数据库中实现内连接、左连接、右连接
  16. 用火箭送快递?淘宝宣布联合蓝箭航天起启动“宝箭”计划...
  17. latex 打出罗马数字
  18. Surrogate mother是代孕妈妈,那么,Surrogate parent呢?
  19. 【协议】NVMe over RoCE 初探 SATA接口(AHCI协议)、PCIe 接口(NVMe 协议)
  20. 关于Vivado综合选项——Out of context per IP和Gobal

热门文章

  1. 计算机打音乐光辉岁月,光辉岁月(完美版)
  2. 莫队--2038: [2009国家集训队]小Z的袜子(hose)
  3. 谢希仁计算机网络第七版 以太网单播和多播MAC地址范围[纠错]
  4. 基类与派生类的类型转换
  5. 最长反链(bzoj 1143: [CTSC2008]祭祀river)
  6. 2017CCPC哈尔滨 D:X-Men
  7. Matlab 小波变换dwt和wavedec
  8. Histogram Normalization 图像直方图归一化
  9. 自定义数组名做参数(传指针教学)
  10. clickhouse 部署+介绍