题意:给一张 nnn 点 mmm 边的连通无向图,qqq 次询问,每次给出一个点集 SSS ,求有多少个不在 SSS 中的点满足删除后 SSS 中存在两个点不连通。

n≤105,m≤2×105,∑∣S∣≤2×105n\leq 10^5,m\leq 2\times 10^5,\sum |S|\leq 2\times 10^5n≤105,m≤2×105,∑∣S∣≤2×105

显然是虚树

题目相当于求 SSS 的割点数量,想到圆方树

建出圆方树后,对于 SSS 中的一对点,它们路径上任意一个圆点都满足条件。答案相当于求两两路径上的圆点的并集。因为不能取 SSS 中的点,所以要减去 ∣S∣|S|∣S∣。

套到虚树上,发现就是虚树覆盖的圆点个数。即对于每个点 uuu ,设 faufa_ufau​ 为其虚树上的父亲,sumusum_usumu​ 为原树上根到 uuu 的圆点个数。那么答案为 ∑(sumu−sumfau)\sum(sum_u-sum_{fa_u})∑(sumu​−sumfau​​)。

注意要特判 lca⁡(S)\operatorname{lca}(S)lca(S)

复杂度 O(n+m+∑∣S∣log⁡∣S∣)O(n+m+\sum|S|\log |S|)O(n+m+∑∣S∣log∣S∣)

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cctype>
#include <vector>
#include <algorithm>
#define MAXN 400005
#define MAXM 800005
using namespace std;
inline int read()
{int ans=0;char c=getchar();while (!isdigit(c)) c=getchar();while (isdigit(c)) ans=(ans<<3)+(ans<<1)+(c^48),c=getchar();return ans;
}
struct edge{int u,v;}e[MAXM];
int head[MAXN],nxt[MAXM],cnt;
inline void addnode(int u,int v)
{e[++cnt]=(edge){u,v};nxt[cnt]=head[u];head[u]=cnt;
}
int n,m;
int dfn[MAXN],low[MAXN],tim;
int stk[MAXN],tp,vis[MAXN],bcc[MAXN],vcnt;
vector<int> rtt[MAXN];
void tarjan(int u)
{dfn[u]=low[u]=++tim;for (int i=head[u];i;i=nxt[i]){if (!vis[i>>1]&&!bcc[i>>1]) vis[(stk[++tp]=i)>>1]=1;if (!dfn[e[i].v]){tarjan(e[i].v);low[u]=min(low[u],low[e[i].v]);if (dfn[u]==low[e[i].v]){rtt[u].push_back(bcc[i>>1]=++vcnt);rtt[bcc[i>>1]].push_back(u);while (vis[i>>1]){int t=stk[tp--];vis[t>>1]=0;rtt[bcc[t>>1]=vcnt].push_back(e[t].v);}}}else low[u]=min(low[u],dfn[e[i].v]);}
}
int sum[MAXN],dep[MAXN],fa[MAXN][20];
void dfs(int u)
{dfn[u]=++tim;for (int i=1;i<20;i++) fa[u][i]=fa[fa[u][i-1]][i-1];for (int i=0;i<(int)rtt[u].size();i++)if (!dep[rtt[u][i]]){dep[rtt[u][i]]=dep[u]+1;sum[rtt[u][i]]=sum[u]+(rtt[u][i]<=n);fa[rtt[u][i]][0]=u;dfs(rtt[u][i]);   }
}
inline int lca(int x,int y)
{if (dep[x]<dep[y]) swap(x,y);int t=dep[x]-dep[y];for (int i=0;(1<<i)<=t;i++) if (t&(1<<i)) x=fa[x][i];if (x==y) return x;for (int i=19;i>=0;i--) if (fa[x][i]!=fa[y][i]) x=fa[x][i],y=fa[y][i];return fa[x][0];
}
int lis[MAXM],len;
inline bool cmp(const int& x,const int& y){return dfn[x]<dfn[y];}
inline void solve()
{sort(lis+1,lis+len+1,cmp);int res=len;for (int i=1;i<res;i++) lis[++len]=lca(lis[i],lis[i+1]);sort(lis+1,lis+len+1,cmp);len=unique(lis+1,lis+len+1)-lis-1;int ans=0;tp=0;for (int i=1;i<=len;i++){while (tp&&lca(stk[tp],lis[i])!=stk[tp]) --tp;ans+=(tp? sum[lis[i]]-sum[stk[tp]]:(lis[i]<=n));stk[++tp]=lis[i];}printf("%d\n",ans-res);
}
int main()
{for (int T=read();T;T--){n=read(),m=read();cnt=1;memset(head,0,sizeof(head));memset(nxt,0,sizeof(nxt));memset(bcc,0,sizeof(bcc));memset(dep,0,sizeof(dep));memset(sum,0,sizeof(sum));memset(dfn,0,sizeof(dfn));for (int i=1;i<=vcnt;i++) rtt[i].clear();tim=tp=0;for (int i=1;i<=m;i++){int u,v;u=read(),v=read();addnode(u,v),addnode(v,u);}vcnt=n;tarjan(1);for (int i=n+1;i<=vcnt;i++) {sort(rtt[i].begin(),rtt[i].end());rtt[i].erase(unique(rtt[i].begin(),rtt[i].end()),rtt[i].end());}dep[1]=sum[1]=1,tim=0;dfs(1);for (int q=read();q;q--){len=read();for (int i=1;i<=len;i++) lis[i]=read();solve();}}return 0;
}

【SDOI2018】战略游戏【圆方树】【虚树】相关推荐

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

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

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

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

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

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

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

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

  5. LuoguP4606 [SDOI2018]战略游戏

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

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

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

  7. [bzoj5329][圆方树][虚树]战略游戏

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

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

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

  9. [SDOI2018]战略游戏

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

  10. 【题解】SDOI2018战略游戏

    被CNST的大小卡了好久.一定要开到18呀-- 首先,遇到这种带各种各样环的图先考虑是不是可以建立圆方树,在圆方树上求出答案.然后转化为圆方树之后,我们就将图转化到了树上.答案非常的明显:只要一个圆点 ...

最新文章

  1. [LeetCode]Perfect Squares
  2. Ubuntu 配置Tomcat环境
  3. 模块说和神经网络学说_教师招聘中常见的5种脑机能学说
  4. 排序算法-- 大总结
  5. php依据地理坐标获取国家、省份、城市,及周边数据类
  6. vijos1053 用spfa判断是否存在负环
  7. LeetCode 951. Flip Equivalent Binary Trees
  8. su灯光插件_lightup插件下载|lightup for sketchup下载v4.0中文免费版 附使用教程 - 欧普软件下载...
  9. Win7、Win10中Protel99se不能加载库文件解决方法
  10. python list 添加噪声_在python中为信号添加噪声
  11. 优秀的linux学习网站
  12. WMS 怎么搞定库内拣选与分拣?
  13. Codeforces Round #521 (Div. 3) E. Thematic Contests
  14. 基于JAVA的ICQ系统的设计于实现
  15. 嵌入式产品软件(固件)开发需要考虑的2个方面
  16. vue3+ts 项目空格和回车代码出现红色波浪线
  17. 开发者福利chatGPT软件Build Software. Fast.
  18. 荔枝派Zero(全志V3S)开启alsa,测试codec
  19. 开机上报树梅派2的IP地址到邮箱
  20. Flutter 元宇宙开发教程之通过 Flutter 和增强现实实现 Metaverse

热门文章

  1. 假如你学过高数,那你这一辈子都不会忘记这个人
  2. 颠覆认知!关于c²= b² + a²,你不知道的N个事实
  3. 程序员的项目周期(表情包版)
  4. mysql 前缀索引 语法_PHP 之Mysql优化
  5. python时间函数报错_Python Day11-LEGB-global-时间函数
  6. js 定时网页点击_反爬 JS 逆向,扣代码解密分析
  7. 计算机语言平均数怎么算,使用python怎么求三个数的平均值
  8. 3des加密 java php_php 3DES加密如何兼容Java
  9. mysql视图实现的_mysql视图是什么?怎么实现?
  10. 如何查询服务器是否安装系统时间,如何查看系统当前的NTP配置?