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

https://www.lydsy.com/JudgeOnline/problem.php?id=5329

#include<cstdio>
#include<algorithm>
#include<cstring>
#define re register
#define rep(i,s,t) for(re int i=s;i<=t;++i)
using namespace std;
#define ms(a,x) memset(a,x,sizeof a)
#define go1(x) for(re int e=G1.las[x];e;e=G1.nxt[e])
#define go2(x) for(re int e=G2.las[x];e;e=G2.nxt[e])
namespace IO{
#define gc getchar()
#define pc(x) putchar(x)
x=0;int f=1;char ch=gc;while(ch>'9'||ch<'0'){if(ch=='-')f=-1;ch=gc;}
while(ch>='0'&&ch<='9')x=(x<<3)+(x<<1)+ch-'0',ch=gc;x*=f;return;
}
template<typename T>inline void write(T x=0){
T wr[51];wr[0]=0;if(x<0)pc('-'),x=-x;if(!x)pc(48);
while(x)wr[++wr[0]]=x%10,x/=10;while(wr[0])pc(48+wr[wr[0]--]);return;
}
}
using IO::write;
const int N=4e5+11;
struct graph{
int tot;
int nxt[N],las[N],to[N];
graph(){
tot=0,ms(nxt,0),ms(las,0),ms(to,0);
}
inline void clear(){
tot=0,ms(nxt,0),ms(las,0),ms(to,0);
}
nxt[++tot]=las[x];
las[x]=tot;
to[tot]=y;
}
}
}G1,G2;
int T,n,m,x,y,dfc,tot;
int low[N],dfn[N],st[N],dis[N],fa[N],
sz[N],son[N],dep[N],top[N],a[N];
inline void tarjan(int x,int anc){
re int v;
low[x]=dfn[x]=++dfc;
st[++st[0]]=x;
go1(x){
v=G1.to[e];
if(v==anc)continue;
if(!dfn[v]){
tarjan(v,x);
low[x]=min(low[x],low[v]);
if(low[v]>=dfn[x]){
int w;
do{
w=st[st[0]--];
}while(w!=v);
}
}
else
low[x]=min(low[x],dfn[v]);
}
}
inline void dfs1(int x,int anc){
re int v;
sz[x]=1,son[x]=0,fa[x]=anc,
dep[x]=dep[anc]+1,dis[x]=dis[anc]+(x<=n);
go2(x){
v=G2.to[e];
if(v==anc)continue;
dfs1(v,x);
sz[x]+=sz[v];
if(sz[v]>sz[son[x]])
son[x]=v;
}
}
inline void dfs2(int x,int up){
top[x]=up,dfn[x]=++dfc;
if(son[x])dfs2(son[x],up);
go2(x){
int v=G2.to[e];
if(v==fa[x]||v==son[x])continue;
dfs2(v,v);
}
low[x]=dfc;
}
inline bool cmp(int a,int b){
return dfn[a]<dfn[b];
}
inline int lca(int u,int v){
for(;top[u]^top[v];dep[top[u]]>dep[top[v]]?u=fa[top[u]]:v=fa[top[v]]);
return dep[u]<dep[v]?u:v;
}
inline void solve(){
G1.clear(),G2.clear(),dfc=0,st[0]=0;
ms(dfn,0);
gii(n,m),tot=n;
rep(i,1,tot)
if(!dfn[i])
tarjan(i,0);
dfc=0,dfs1(1,0),dfs2(1,1);
int q,k,l,ans;
//rep(i,1,tot)printf("At:%d %d %d\n",dfn[i],low[i],top[i]);
gi(q);
for(;q--;){
gi(k);
rep(i,1,k)gi(a[i]);
sort(a+1,a+k+1,cmp);l=k;
rep(i,1,k-1)a[++l]=lca(a[i],a[i+1]);
sort(a+1,a+l+1,cmp);
l=unique(a+1,a+l+1)-a-1;
ans=a[1]<=n,st[0]=0;
rep(i,1,l){
for(;st[0]&&low[st[st[0]]]<dfn[a[i]];)--st[0];
if(st[0])ans+=dis[a[i]]-dis[st[st[0]]];
st[++st[0]]=a[i];
}
write(ans-k),putchar('\n');
}
}
int main(){
gi(T);
for(;T--;solve());
return 0;
}
code

posted @ 2018-07-08 22:11  Stump  阅读(90)  评论(0编辑  收藏