正题

题目链接:https://www.luogu.com.cn/problem/P4606


题目大意

给出\(n\)个点\(m\)条边的一张图,\(q\)次询问给出一个点集,询问有多少个点割掉后可以是点集中至少一个点对不连通。


解题思路

就是问圆方树上的虚树中的圆点数量,照着统计就好了。

细节有点多,注意不要习惯性的把根节点带进虚树就好了。

时间复杂度\(O(n\log n)\)


code

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
#include<stack>
using namespace std;
const int N=2e5+10;
int T,n,m,q,dfc,cnt,ans,p[N],dfn[N],low[N],s[N];
int pn,dis[N],dep[N],fa[N],top[N],siz[N],son[N];
vector<int> G[N],H[N];stack<int> S;
void tarjan(int x){
dfn[x]=low[x]=++dfc;S.push(x);
for(int i=0;i<H[x].size();i++){
int y=H[x][i];
if(!dfn[y]){
tarjan(y);
low[x]=min(low[x],low[y]);
if(low[y]==dfn[x]){
int k;++n;
do{
k=S.top();S.pop();
G[n].push_back(k);
G[k].push_back(n);
}while(k!=y);
G[n].push_back(x);
G[x].push_back(n);
}
}
else low[x]=min(low[x],dfn[y]);
}
return;
}
void dfs1(int x){
dfn[x]=++dfc;siz[x]=1;
dep[x]=dep[fa[x]]+1;
dis[x]=dis[fa[x]]+(x<=pn);
for(int i=0;i<G[x].size();i++){
int y=G[x][i];
if(y==fa[x])continue;
fa[y]=x;dfs1(y);siz[x]+=siz[y];
if(siz[y]>siz[son[x]])son[x]=y;
}
return;
}
void dfs2(int x){
if(son[x]){
top[son[x]]=top[x];
dfs2(son[x]);
}
for(int i=0;i<G[x].size();i++){
int y=G[x][i];
if(y==fa[x]||y==son[x])continue;
top[y]=y;dfs2(y);
}
return;
}
int LCA(int x,int y){
while(top[x]!=top[y]){
if(dep[top[x]]<dep[top[y]])swap(x,y);
x=fa[top[x]];
}
return (dep[x]<dep[y])?x:y;
}
void Add(int x){
if(!cnt){s[++cnt]=x;return;}
int lca=LCA(x,s[cnt]);
while(cnt>1&&dep[s[cnt-1]]>dep[lca])
ans+=dis[s[cnt]]-dis[s[cnt-1]],cnt--;
if(dep[s[cnt]]>dep[lca])
ans+=dis[s[cnt]]-dis[lca],cnt--;
if(s[cnt]!=lca)s[++cnt]=lca;
s[++cnt]=x;return;
}
bool cmp(int x,int y)
{return dfn[x]<dfn[y];}
int main()
{
scanf("%d",&T);
while(T--){
scanf("%d%d",&n,&m);dfc=0;pn=n;
for(int i=1;i<=2*n;i++)
H[i].clear(),G[i].clear(),dfn[i]=low[i]=son[i]=0;
for(int i=1;i<=m;i++){
int x,y;
scanf("%d%d",&x,&y);
H[x].push_back(y);
H[y].push_back(x);
}
tarjan(1);dfc=0;
dfs1(1);top[1]=1;dfs2(1);
scanf("%d",&q);
while(q--){
scanf("%d",&m);
for(int i=1;i<=m;i++)scanf("%d",&p[i]);
sort(p+1,p+1+m,cmp);cnt=ans=0;
// if(p[1]!=1)s[++cnt]=1;
for(int i=1;i<=m;i++)
Add(p[i]);
while(cnt>1)ans+=dis[s[cnt]]-dis[s[cnt-1]],cnt--;
printf("%d\n",ans-m+(LCA(p[1],p[m])<=pn));
}
}
return 0;
}

P4606-[SDOI2018]战略游戏【圆方树,虚树】的更多相关文章

  1. Luogu P4606 [SDOI2018] 战略游戏 圆方树 虚树

    https://www.luogu.org/problemnew/show/P4606 把原来的图的点双联通分量缩点(每个双联通分量建一个点,每个割点再建一个点)(用符合逻辑的方式)建一棵树(我最开始 ...

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

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

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

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

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

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

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

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

  6. BZOJ.5329.[SDOI2018]战略游戏(圆方树 虚树)

    题目链接 显然先建圆方树,方点权值为0圆点权值为1,两点间的答案就是路径权值和减去起点终点. 对于询问,显然可以建虚树.但是只需要计算两关键点间路径权值,所以不需要建出虚树.统计DFS序相邻的两关键点 ...

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

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

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

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

  9. 洛谷P4606 [SDOI2018]战略游戏 [广义圆方树]

    传送门 思路 先考虑两点如何使他们不连通. 显然路径上所有的割点都满足条件. 多个点呢?也是这样的. 于是可以想到圆方树.一个点集的答案就是它的虚树里圆点个数减去点集大小. 可以把点按dfs序排序,然 ...

  10. 【SDOI2018】战略游戏(同时普及虚树)

    先看一道虚树普及题:给你一棵 $n$ 个点的树,$m$ 次询问,每次询问给你 $k$ 个关键点,求把这些点都连起来的路径并的最短长度.$1\le n,m\le 100000,\space 1\le \ ...

随机推荐

  1. java-通过ip获取地址

    添加maven依赖 <dependency> <groupId>cn.hutool</groupId> <artifactId>hutool-all&l ...

  2. ASP.NET Core教程:在ASP.NET Core中使用HttPClient调用WebService

    一.前言 在以前的一篇文章中,曾经讲述过如何在ASP.NET Core中调用WebService.但是那种方式是通过静态引用的方式去调用的,如果是在生产环境中,肯定不能使用这种方式去调用,幸运的是微软 ...

  3. vim conf文件配色

    VIM conf文件配色 一.配置文件 1.下载Nginx配置文件的语法文件:nginx.vim wget http://www.vim.org/scripts/download_script.php ...

  4. NIO中的File

    package nio; import java.io.IOException; import java.nio.charset.Charset; import java.nio.file.Files ...

  5. jwt《token》

    payload与claims只能存在一个这部分是jwt源码:依赖如下:官方文档的依赖 <dependency> <groupId>io.jsonwebtoken</gro ...

  6. golang中的三个点 ‘...‘ 的用法

    '-' 其实是go的一种语法糖. 它的第一个用法主要是用于函数有多个不定参数的情况,可以接受多个不确定数量的参数. 第二个用法是slice可以被打散进行传递. 下面直接上例子: func test1( ...

  7. 在ES5中模拟类

    1.Object.create()方法创建一个新对象,使用现有的对象来提供新创建的对象的__proto__. var _this = Object.create(fn.prototype);这句代码的 ...

  8. 使用let实现循环小例子

    <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title> ...

  9. 【WPF】 OxyPlot图表控件学习

    最近在学习OxyPlot图表控件,一些基本的学习心得,在这里记录一下,方便以后进行查找.   一.引用 OxyPlot控件可以直接在VS的 " Nuget " 里面下载   选择: ...

  10. Java数八大据类型的拓展

    public class 数据类型拓展问题 { public static void main(String[] args) { //================================= ...