Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include<bits/stdc++.h>
- using namespace std;
- #define gc c=getchar()
- #define r(x) read(x)
- #define ll long long
- template<typename T>
- inline void read(T&x){
- x=0;T k=1;char gc;
- while(!isdigit(c)){if(c=='-')k=-1;gc;}
- while(isdigit(c)){x=x*10+c-'0';gc;}x*=k;
- }
- const int N=2e5+7;
- int n,m,tot;
- namespace Imag{
- int sum[N];
- vector<int>G[N];
- int ans;
- void dfs(int x,int pre){
- ans+=sum[x]-pre;
- for(int i=0;i<G[x].size();++i){
- dfs(G[x][i],sum[x]);
- }
- G[x].clear();
- }
- inline int query(int x,int pre){
- ans=0;
- dfs(x,pre);
- return ans;
- }
- }
- namespace Tree{
- vector<int>G[N];
- int fa[N];
- int dep[N];
- int son[N];
- int siz[N];
- using Imag::sum;
- void dfs1(int x,int f){
- fa[x]=f;
- siz[x]=1;
- dep[x]=dep[f]+1;
- sum[x]=sum[f]+(x<=n);
- for(int i=0;i<G[x].size();++i){
- int v=G[x][i];
- dfs1(v,x);
- siz[x]+=siz[v];
- if(siz[son[x]]<siz[v])son[x]=v;
- }
- }
- int top[N];
- int dfn[N];
- int dfs_clock;
- void dfs2(int x,int t){
- top[x]=t;
- dfn[x]=++dfs_clock;
- if(!son[x])return ;
- dfs2(son[x],t);
- for(int i=0;i<G[x].size();++i){
- int v=G[x][i];
- if(v==son[x])continue;
- dfs2(v,v);
- }
- }
- inline int lca(int u,int v){
- while(top[u]!=top[v]){
- if(dep[top[u]]<dep[top[v]])swap(u,v);
- u=fa[top[u]];
- }
- return dep[u]<dep[v]?u:v;
- }
- inline bool cmp(const int &a,const int &b){
- return dfn[a]<dfn[b];
- }
- int Top;
- int sta[N];
- inline void ins(int x){
- if(Top==0){
- sta[++Top]=x;
- return ;
- }
- int t=lca(x,sta[Top]);
- while(Top>1&&dep[sta[Top-1]]>=dep[t]){
- Imag::G[sta[Top-1]].push_back(sta[Top]);
- Top--;
- }
- if(sta[Top]!=t){
- Imag::G[t].push_back(sta[Top]);
- sta[Top]=t;
- }
- sta[++Top]=x;
- }
- int a[N];
- inline void solve(){
- dfs1(1,0);
- dfs2(1,1);
- int q;r(q);
- while(q--){
- int c;r(c);
- for(int i=1;i<=c;++i)r(a[i]);
- sort(a+1,a+c+1,cmp);
- Top=0;
- int LCA=a[1];
- for(int i=1;i<=c;++i)ins(a[i]),LCA=lca(LCA,a[i]);
- while(Top>1){
- Imag::G[sta[Top-1]].push_back(sta[Top]);
- Top--;
- }
- printf("%d\n",Imag::query(LCA,sum[fa[LCA]])-c);
- }
- for(int i=1;i<=tot;++i){
- son[i]=0;
- G[i].clear();
- }
- dfs_clock=0;
- }
- }
- namespace Graph{
- vector<int>G[N];
- int dfn[N];
- int low[N];
- int dfs_clock;
- int top;
- int sta[N];
- bool in[N];
- void dfs(int x,int f){
- dfn[x]=low[x]=++dfs_clock;
- sta[++top]=x;
- for(int i=0;i<G[x].size();++i){
- int v=G[x][i];
- if(v==f)continue;
- if(!dfn[v]){
- dfs(v,x);
- low[x]=min(low[x],low[v]);
- if(low[v]>=dfn[x]){
- Tree::G[x].push_back(++tot);
- int t;
- do{
- t=sta[top--];
- Tree::G[tot].push_back(t);
- }while(t!=v);
- }
- }
- else {
- low[x]=min(low[x],dfn[v]);
- }
- }
- }
- inline void work(){
- r(n),r(m);tot=n;
- for(int i=1;i<=m;++i){
- int u,v;r(u),r(v);
- G[u].push_back(v);
- G[v].push_back(u);
- }
- dfs(1,0);
- for(int i=1;i<=n;++i){
- G[i].clear();
- dfn[i]=0;
- }
- dfs_clock=0;
- }
- }
- int main(){
- // freopen(".in","r",stdin);
- // freopen(".out","w",stdout);
- int T;r(T);
- while(T--){
- Graph::work();
- Tree::solve();
- }
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment