被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战略游戏的更多相关文章

  1. [SDOI2018]战略游戏 圆方树,树链剖分

    [SDOI2018]战略游戏 这题是道路相遇(题解)的升级版,询问的两个点变成了\(S\)个点. LG传送门 还是先建出圆方树,考虑对于询问的\(S\)个点,答案就是圆方树上能包含这些点的最小连通块中 ...

  2. bzoj5315/luoguP4517 [SDOI2018]战略游戏(圆方树,虚树)

    bzoj5315/luoguP4517 [SDOI2018]战略游戏(圆方树,虚树) bzoj Luogu 题目描述略(太长了) 题解时间 切掉一个点,连通性变化. 上圆方树. $ \sum |S| ...

  3. [bzoj5329] P4606 [SDOI2018]战略游戏

    P4606 [SDOI2018]战略游戏:广义圆方树 其实会了圆方树就不难,达不到黑,最多算个紫 那个转换到圆方树上以后的处理方法,画画图就能看出来,所以做图论题一定要多画图,并把图画清楚点啊!! 但 ...

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

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

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

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

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

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

  7. bzoj 5329: [Sdoi2018]战略游戏

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

  8. luogu P4606 [SDOI2018]战略游戏

    LINK:战略游戏 一道很有价值的题目.这道题 一张无向联通图 每次询问给出K个关键点 问摧毁图中哪个点可以使得这K个关键的两两之间有一对不能联通 去掉的这个点不能是关键点 求方案数. 可以发现 当K ...

  9. 洛谷P4606 [SDOI2018]战略游戏 【圆方树 + 虚树】

    题目链接 洛谷P4606 双倍经验:弱化版 题解 两点之间必经的点就是圆方树上两点之间的圆点 所以只需建出圆方树 每次询问建出虚树,统计一下虚树边上有多少圆点即可 还要讨论一下经不经过根\(1\)的情 ...

随机推荐

  1. springmvc请求数据的流程。

    验证了我说的,从model层中拿来的数据,不管什么类型,都是通过隐含模型,中转,放入request中的.除非你特意把这些数据放到session域中 流程含义解释:(来自网友)(1)HTTP请求到达we ...

  2. ctf题目writeup(4)

    2019.1.31 题目:这次都是web的了...(自己只略接触隐写杂项web这些简单的东西...) 题目地址:https://www.ichunqiu.com/battalion 1. 打开链接: ...

  3. ubuntu64位运行32位程序

    sudo dpkg --add-architecture i386 sudo apt install libc6:i386 转:https://blog.csdn.net/zoomdy/article ...

  4. 嵌入式框架Zorb Framework搭建五:事件的实现

    我是卓波,我是一名嵌入式工程师,我万万没想到我会在这里跟大家吹牛皮. 嵌入式框架Zorb Framework搭建过程 嵌入式框架Zorb Framework搭建一:嵌入式环境搭建.调试输出和建立时间系 ...

  5. 动态规划(DP)算法

    参考https://blog.csdn.net/libosbo/article/details/80038549 动态规划是求解决策过程最优化的数学方法.利用各个阶段之间的关系,逐个求解,最终求得全局 ...

  6. WPF中ContextMenu(右键菜单)使用Command在部分控件上默认为灰色的处理方法

    原文:WPF中ContextMenu(右键菜单)使用Command在部分控件上默认为灰色的处理方法 问题描述 今天发现如果我想在一个TextBlock弄一个右键菜单,并且使用Command绑定,结果发 ...

  7. [Jmeter]jmeter数据库性能测试配置

    学习jmeter过程中,记录一些学习过程中的点点滴滴,用于备忘.本文主要介绍的是如何创建一个简单的测试计划用户测试数据库服务器. 一.添加线程组 二.添加JDBC请求 1.在第一步里面定义并发用户以及 ...

  8. echarts的pie图中,各区块颜色的调整

    今天在学习使用echarts生成各种图表. 然后在使用pie图时出现我无论怎么更改代码中的颜色,pie图中各块的颜色都十分相近,几乎没法区别块与块之间的区别,如下图: 在下图中,除了其中一块的是红色的 ...

  9. RTL8195AM开发板使用

    1. 本次使用RTL8195AM测试一下,原厂资源地址:https://os.mbed.com/platforms/Realtek-RTL8195AM/ 2. 由于板子支持mbed,所以把CON2连接 ...

  10. 导入execl到数据库mysql

    GwykhrenyuankuList <body jwcid="$content$"> <span jwcid="@components/AppBord ...