喜闻乐见的圆方树+虚树

图上不好做,先建出圆方树。

然后答案就是没被选到的且至少有两条边可以走到被选中的点的圆点的数量。

语文不好,但结论画画图即可得出。

然后套路建出虚树。

发现在虚树上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]战略游戏(圆方树+虚树)的更多相关文章

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

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

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

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

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

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

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

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

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

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

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

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

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

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

  8. 仙人掌 && 圆方树 && 虚树 总结

    仙人掌 && 圆方树 && 虚树 总结 Part1 仙人掌 定义 仙人掌是满足以下两个限制的图: 图完全联通. 不存在一条边处在两个环中. 其中第二个限制让仙人掌的题做 ...

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

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

随机推荐

  1. vs code--使用教程

    这是Cnode论坛上的i5ting写的,很详细 教程地址 这个是微软官方的英文版的教程,这个更详细一些 微软官方vs code教程

  2. [bzoj3680]吊打XXX_模拟退火

    吊打XXX bzoj-3680 题目大意:在平面上给定n个点,每个点有一个权值.请在平面上找出一个点(不一定在这n个点内找)使得这个点到n个点的距离*权值最小,即求这n个点的重心. 注释:$1\le ...

  3. LDA 两种含义

    关于LDA有两种含义,一种是线性判别分析(Linear Discriminant Analysis),一种是概率主题模型:隐含狄利克雷分布(Latent Dirichlet Allocation,简称 ...

  4. 项目PMO工作

     算起来.这是第一次以项目PMO人员的身份參与项目,尽管非常可惜没有从头參与,也没有參与到项目结束,仅仅有短短的两个月.但对项目PMO也可略窥一斑.如今就当个流水账写一写吧. 进项目组的时候,是中 ...

  5. Codeforces Round 313(div1)

    A题: 题目大意: 给出内角全为120度的六边形的六条边的边长,求由多少边长为1的等边三角形构成. 解题思路: 将六边形补全为一个大的等边三角形,则大的等边三角形的边长为六边形的相邻三边之和,接着减去 ...

  6. Converter实现Date类型转换

    1.springmvc-config.xml配置 <?xml version="1.0" encoding="UTF-8"?> <beans ...

  7. ActionFilterAttribute

    https://msdn.microsoft.com/en-us/library/system.web.mvc.actionfilterattribute.onactionexecuting(v=vs ...

  8. 康少带你玩转JavaScript

    目录 1.JavaScript简述 2.JavaScript引入方式 3.JavaScript语法基础 4.JavaScript数据类型 5.运算符 6.流程控制 7.函数 8.内置对象和方法 1.J ...

  9. iOS开发中UIDatePicker控件的使用方法简介

    iOS上的选择时间日期的控件是这样的,左边是时间和日期混合,右边是单纯的日期模式. 您可以选择自己需要的模式,Time, Date,Date and Time  , Count Down Timer四 ...

  10. Unity3d Time

    using UnityEngine; using System.Collections; public class test1 : MonoBehaviour { public float angle ...