[SDOI2018]战略游戏(圆方树+虚树)
喜闻乐见的圆方树+虚树
图上不好做,先建出圆方树。
然后答案就是没被选到的且至少有两条边可以走到被选中的点的圆点的数量。
语文不好,但结论画画图即可得出。
然后套路建出虚树。
发现在虚树上DP可以得出答案。
所以在虚树上DP即可。
代码极丑
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<algorithm>
using namespace std;
const int N=401000;
struct Graph{
struct edge{
int to,nxt;
}e[N*2];
int cnt,head[N];
void add_edge(int u,int v){
cnt++;
e[cnt].nxt=head[u];
e[cnt].to=v;
head[u]=cnt;
}
}g1,g2,g3;
int dfn[N],low[N],tim,stack[N],top,num;
void Tarjan(int u){
dfn[u]=low[u]=++tim;
stack[++top]=u;
for(int i=g1.head[u];i;i=g1.e[i].nxt){
int v=g1.e[i].to;
if(dfn[v]==0){
Tarjan(v);
low[u]=min(low[u],low[v]);
if(low[v]>=dfn[u]){
g2.add_edge(++num,u);
g2.add_edge(u,num);
int x;
do{
x=stack[top--];
g2.add_edge(x,num);
g2.add_edge(num,x);
}while(x!=v);
}
}
else low[u]=min(low[u],dfn[v]);
}
}
int w[N],fa[N][22],dep[N],tot,n;
void dfs(int u,int f){
w[u]=w[f]+(u<=n?1:0);
fa[u][0]=f;dep[u]=dep[f]+1;dfn[u]=++tot;
for(int i=1;i<=20;i++)fa[u][i]=fa[fa[u][i-1]][i-1];
for(int i=g2.head[u];i;i=g2.e[i].nxt){
int v=g2.e[i].to;
if(v==f)continue;
dfs(v,u);
}
}
bool cmp(int x,int y){
return dfn[x]<dfn[y];
}
int getlca(int x,int y){
if(dep[x]<dep[y])swap(x,y);
for(int i=20;i>=0;i--)
if(dep[fa[x][i]]>=dep[y])x=fa[x][i];
if(x==y)return x;
for(int i=20;i>=0;i--)
if(fa[x][i]!=fa[y][i])x=fa[x][i],y=fa[y][i];
return fa[x][0];
}
int q[N],Tot;
void ins(int x){
if(top<=1){stack[++top]=x;return;}
int lca=getlca(stack[top],x);
if(lca==stack[top]){stack[++top]=x;return;}
while(top&&dfn[stack[top-1]]>=dfn[lca])g3.add_edge(stack[top-1],stack[top]),top--;
if(stack[top]!=lca)g3.add_edge(lca,stack[top]),stack[top]=lca,q[++Tot]=lca;
stack[++top]=x;
}
int ans;
bool book[N];
void get_ans(int u){
if(u==1&&book[u]==0){
int tmp=0;
for(int i=g3.head[u];i;i=g3.e[i].nxt)tmp++;
if(tmp==1){
for(int i=g3.head[u];i;i=g3.e[i].nxt){
int v=g3.e[i].to;
get_ans(v);
}
return;
}
}
if(!book[u]&&u<=n)ans++;
for(int i=g3.head[u];i;i=g3.e[i].nxt){
int v=g3.e[i].to;
ans+=w[v]-w[u];
if(v<=n)ans--;
get_ans(v);
}
}
void clear(){
while(Tot)book[q[Tot]]=g3.head[q[Tot]]=0,Tot--;
g3.cnt=0;top=0;ans=0;
}
void init(){
memset(g1.head,0,sizeof(g1.head));
g1.cnt=0;
memset(g2.head,0,sizeof(g2.head));
g2.cnt=0;
tim=0;top=0;tot=0;
memset(dfn,0,sizeof(dfn));
}
int read(){
int sum=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){sum=sum*10+ch-'0';ch=getchar();}
return sum*f;
}
int m,Q,a[N];
int main(){
// freopen("xdx.out","w",stdout);
int T=read();
while(T--){
init();
num=n=read();m=read();
for(int i=1;i<=m;i++){
int u=read(),v=read();
g1.add_edge(u,v);g1.add_edge(v,u);
}
Tarjan(1);
dfs(1,0);
Q=read();
while(Q--){
clear();
int k=read();
for(int i=1;i<=k;i++)a[i]=read(),book[a[i]]=1,q[++Tot]=a[i];
sort(a+1,a+1+k,cmp);
if(a[1]!=1)stack[++top]=1,q[++Tot]=1;
for(int i=1;i<=k;i++)ins(a[i]);
for(int i=1;i<top;i++)g3.add_edge(stack[i],stack[i+1]);
get_ans(1);
printf("%d\n",ans);
}
}
return 0;
}
[SDOI2018]战略游戏(圆方树+虚树)的更多相关文章
- bzoj5315/luoguP4517 [SDOI2018]战略游戏(圆方树,虚树)
bzoj5315/luoguP4517 [SDOI2018]战略游戏(圆方树,虚树) bzoj Luogu 题目描述略(太长了) 题解时间 切掉一个点,连通性变化. 上圆方树. $ \sum |S| ...
- [SDOI2018]战略游戏 圆方树,树链剖分
[SDOI2018]战略游戏 这题是道路相遇(题解)的升级版,询问的两个点变成了\(S\)个点. LG传送门 还是先建出圆方树,考虑对于询问的\(S\)个点,答案就是圆方树上能包含这些点的最小连通块中 ...
- BZOJ5329:[SDOI2018]战略游戏(圆方树,虚树)
Description 省选临近,放飞自我的小Q无心刷题,于是怂恿小C和他一起颓废,玩起了一款战略游戏. 这款战略游戏的地图由n个城市以及m条连接这些城市的双向道路构成,并且从任意一个城市出发总能沿着 ...
- Luogu4606 SDOI2018 战略游戏 圆方树、虚树、链并
传送门 弱化版 考虑到去掉一个点使得存在两个点不连通的形式类似割点,不难想到建立圆方树.那么在圆方树上对于给出的关键点建立虚树之后,我们需要求的就是虚树路径上所有圆点的数量减去关键点的数量. 因为没有 ...
- BZOJ.5329.[SDOI2018]战略游戏(圆方树 虚树)
题目链接 显然先建圆方树,方点权值为0圆点权值为1,两点间的答案就是路径权值和减去起点终点. 对于询问,显然可以建虚树.但是只需要计算两关键点间路径权值,所以不需要建出虚树.统计DFS序相邻的两关键点 ...
- Luogu P4606 [SDOI2018] 战略游戏 圆方树 虚树
https://www.luogu.org/problemnew/show/P4606 把原来的图的点双联通分量缩点(每个双联通分量建一个点,每个割点再建一个点)(用符合逻辑的方式)建一棵树(我最开始 ...
- 【SDOI2018】战略游戏(同时普及虚树)
先看一道虚树普及题:给你一棵 $n$ 个点的树,$m$ 次询问,每次询问给你 $k$ 个关键点,求把这些点都连起来的路径并的最短长度.$1\le n,m\le 100000,\space 1\le \ ...
- 仙人掌 && 圆方树 && 虚树 总结
仙人掌 && 圆方树 && 虚树 总结 Part1 仙人掌 定义 仙人掌是满足以下两个限制的图: 图完全联通. 不存在一条边处在两个环中. 其中第二个限制让仙人掌的题做 ...
- [BZOJ5329][SDOI2018]战略游戏
bzoj luogu Description 省选临近,放飞自我的小Q无心刷题,于是怂恿小C和他一起颓废,玩起了一款战略游戏. 这款战略游戏的地图由n个城市以及m条连接这些城市的双向道路构成,并且从任 ...
随机推荐
- 【ACM】hdu_1092_A+BIV_201307261630
A+B for Input-Output Practice (IV)Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/3276 ...
- SWT中嵌入Swing的JTextFeild却不能编辑
SWT中嵌入Swing的JTextFeild却不能编辑 学习了:http://www.iteye.com/problems/49487 膜拜一下 org 竟然有这样的坑,需要在中间添加一个JApp ...
- ThinkPHP模版引擎之变量输出具体解释
ThinkPHP模版引擎之变量输出具体解释 使用ThinkPHP开发有一定时间了,今日对ThinkPHP的模板引擎变量解析深入了解了一下.做出一些总结,分享给大家供大家參考. 详细分析例如以下: 我们 ...
- 项目PMO工作
算起来.这是第一次以项目PMO人员的身份參与项目,尽管非常可惜没有从头參与,也没有參与到项目结束,仅仅有短短的两个月.但对项目PMO也可略窥一斑.如今就当个流水账写一写吧. 进项目组的时候,是中 ...
- 错误: su: 无法设置组: 不允许的操作
到 /bin目录下,用ls -l 看下su文件的权限是不是rwxr-xr-x或者-rwxrwxrwx 执行这条命令chmod ug+s su
- VIM中括号的自动补全与删除
先放来源 http://oldj.net/article/vim-parenthesis/ 很多现代 IDE 都有自动补全配对括号的功能,比如输入了左括号“(”,IDE 就自动在后面添加一个对应的右括 ...
- Working with SQL Server LocalDB
https://docs.asp.net/en/latest/tutorials/first-mvc-app/working-with-sql.html The ApplicationDbContex ...
- python print 显示不同的字体
显示格式: print('\033[显示方式;字体颜色;背景色m.....\033[0m') ------------------------------- 显示方式 | 效果 ----------- ...
- mysql 强制修改密码
mysql忘记密码时强制修改步骤如下: 1.用命令编辑配置文件/etc/my.cnf 2.添加一条语句使其变为不用密码就能进入的状态 skip-grant-tables 3.保存并退出,然后再命令行输 ...
- 关于React-native的介绍以及环境搭建
React-Native介绍(后面内容的RN就是指react-native) 由facebook公司推出的,基于react,能开发原生app 原理: 1. 利用react框架写好js代码 2. 利用p ...