【SDOI2018】战略游戏【圆方树】【虚树】
题意:给一张 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】战略游戏【圆方树】【虚树】相关推荐
- [BZOJ5329][Sdoi2018]战略游戏 圆方树+虚树
5329: [Sdoi2018]战略游戏 Time Limit: 30 Sec Memory Limit: 512 MB Submit: 174 Solved: 109 [Submit][Stat ...
- BZOJ5329:[SDOI2018]战略游戏(圆方树,虚树)
Description 省选临近,放飞自我的小Q无心刷题,于是怂恿小C和他一起颓废,玩起了一款战略游戏. 这款战略游戏的地图由n个城市以及m条连接这些城市的双向道路构成,并且从任意一个城市出发总能沿着 ...
- Luogu4606 SDOI2018 战略游戏 圆方树、虚树、链并
传送门 弱化版 考虑到去掉一个点使得存在两个点不连通的形式类似割点,不难想到建立圆方树.那么在圆方树上对于给出的关键点建立虚树之后,我们需要求的就是虚树路径上所有圆点的数量减去关键点的数量. 因为没有 ...
- [SDOI2018]战略游戏 圆方树+虚树
Description 给T组数据. 每组数据给你一个n个点的无向图,保证图联通,给q个询问. 每个询问给k个节点,问每一次询问中,求有多少个点在断掉他之后可以使图中两个点不连通. Sample In ...
- LuoguP4606 [SDOI2018]战略游戏
LuoguP4606 [SDOI2018]战略游戏 题目描述 题目描述 省选临近,放飞自我的小 QQ 无心刷题,于是怂恿小 CC 和他一起颓废,玩起了一款战略游戏. 这款战略游戏的地图由 nn 个城市 ...
- [BZOJ5329][SDOI2018]战略游戏
bzoj luogu Description 省选临近,放飞自我的小Q无心刷题,于是怂恿小C和他一起颓废,玩起了一款战略游戏. 这款战略游戏的地图由n个城市以及m条连接这些城市的双向道路构成,并且从任 ...
- [bzoj5329][圆方树][虚树]战略游戏
Description 省选临近,放飞自我的小Q无心刷题,于是怂恿小C和他一起颓废,玩起了一款战略游戏. 这款战略游戏的地图由n个城市以及m条连接这些城市的双向道路构成,并且从任意一个城市出发总能沿着 ...
- BZOJ5329: [SDOI2018]战略游戏——题解
https://www.lydsy.com/JudgeOnline/problem.php?id=5329 https://www.luogu.org/problemnew/show/P4606 省选 ...
- [SDOI2018]战略游戏
题目描述 省选临近,放飞自我的小Q无心刷题,于是怂恿小C和他一起颓废,玩起了一款战略游戏. 这款战略游戏的地图由n个城市以及m条连接这些城市的双向道路构成,并且从任意一个城市出发总能沿着道路走到 任意 ...
- 【题解】SDOI2018战略游戏
被CNST的大小卡了好久.一定要开到18呀-- 首先,遇到这种带各种各样环的图先考虑是不是可以建立圆方树,在圆方树上求出答案.然后转化为圆方树之后,我们就将图转化到了树上.答案非常的明显:只要一个圆点 ...
最新文章
- [LeetCode]Perfect Squares
- Ubuntu 配置Tomcat环境
- 模块说和神经网络学说_教师招聘中常见的5种脑机能学说
- 排序算法-- 大总结
- php依据地理坐标获取国家、省份、城市,及周边数据类
- vijos1053 用spfa判断是否存在负环
- LeetCode 951. Flip Equivalent Binary Trees
- su灯光插件_lightup插件下载|lightup for sketchup下载v4.0中文免费版 附使用教程 - 欧普软件下载...
- Win7、Win10中Protel99se不能加载库文件解决方法
- python list 添加噪声_在python中为信号添加噪声
- 优秀的linux学习网站
- WMS 怎么搞定库内拣选与分拣?
- Codeforces Round #521 (Div. 3) E. Thematic Contests
- 基于JAVA的ICQ系统的设计于实现
- 嵌入式产品软件(固件)开发需要考虑的2个方面
- vue3+ts 项目空格和回车代码出现红色波浪线
- 开发者福利chatGPT软件Build Software. Fast.
- 荔枝派Zero(全志V3S)开启alsa,测试codec
- 开机上报树梅派2的IP地址到邮箱
- Flutter 元宇宙开发教程之通过 Flutter 和增强现实实现 Metaverse
热门文章
- 假如你学过高数,那你这一辈子都不会忘记这个人
- 颠覆认知!关于c²= b² + a²,你不知道的N个事实
- 程序员的项目周期(表情包版)
- mysql 前缀索引 语法_PHP 之Mysql优化
- python时间函数报错_Python Day11-LEGB-global-时间函数
- js 定时网页点击_反爬 JS 逆向,扣代码解密分析
- 计算机语言平均数怎么算,使用python怎么求三个数的平均值
- 3des加密 java php_php 3DES加密如何兼容Java
- mysql视图实现的_mysql视图是什么?怎么实现?
- 如何查询服务器是否安装系统时间,如何查看系统当前的NTP配置?