MnZn求助,0pts,样例过了
查看原帖
MnZn求助,0pts,样例过了
1049442
OIerror楼主2024/11/23 20:23
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
int n,m;
struct edge
{
	int nxt,to;
}g[400001],e[400001];
int first[200001],head[200001],sum,tot;
int dfn[200001],low[200001],vistime,idx;
int s[200001],top;
int id[200001],cnt;
int val[200001],dep[200001],f[200001][21];
int a[200001];
bool cmp(int a,int b)
{
	return id[a]<id[b];
}
void add_edge(int u,int v)
{
	sum++;
	g[sum].nxt=first[u];
	g[sum].to=v;
	first[u]=sum;
}
void add_tree(int u,int v)
{
	tot++;
	e[tot].nxt=head[u];
	e[tot].to=v;
	head[u]=tot;
}
void clear()
{
	sum=tot=vistime=top=cnt=0;
	idx=n;
	for(int i=1;i<=2*n;i++)
	{
		first[i]=head[i]=dfn[i]=low[i]=s[i]=id[i]=val[i]=dep[i]=0;
		for(int t=0;t<=20;t++)
		{
			f[i][t]=0;
		}
	}
	for(int i=1;i<=2*m;i++)
	{
		g[i].nxt=g[i].to=0;
		e[i].nxt=e[i].to=0;
	}
}
void tarjan(int u)
{
	dfn[u]=low[u]=++vistime;
	s[++top]=u;
	for(int i=first[u];i;i=g[i].nxt)
	{
		int v=g[i].to;
		if(!dfn[v])
		{
			tarjan(v);
			low[u]=min(low[u],low[v]);
			if(low[v]>=dfn[u])
			{
				int k;
				idx++;
				add_tree(u,idx);
				add_tree(idx,u);
				do
				{
					k=s[top];
					top--;
					add_tree(k,idx);
					add_tree(idx,k);
				}
				while(k!=v);
			}
		}
	}
}
void dfs(int u,int father)
{
	id[u]=++cnt;
	dep[u]=dep[father]+1;
	val[u]=val[father]+(u<=n);
	f[u][0]=father;
	for(int i=head[u];i;i=e[i].nxt)
	{
		int v=e[i].to;
		if(v!=father)
		{
			dfs(v,u);
		}
	}
}
void init()
{
	for(int t=1;t<=20;t++)
	{
		for(int i=1;i<=idx;i++)
		{
			f[i][t]=f[f[i][t-1]][t-1];
		}
	}
}
int LCA(int x,int y)
{
	if(dep[x]<dep[y])
	{
		swap(x,y);
	}
	for(int t=20;t>=0;t--)
	{
		if(dep[f[x][t]]>=dep[y])
		{
			x=f[x][t];
		}
	}
	if(x==y)
	{
		return x;
	}
	for(int t=20;t>=0;t--)
	{
		if(f[x][t]!=f[y][t])
		{
			x=f[x][t];
			y=f[y][t];
		}
	}
	return f[x][0];
}
int main()
{
	int T;
	scanf("%d",&T);
	while(T--)
	{
		scanf("%d%d",&n,&m);
		clear();
		for(int i=1;i<=m;i++)
		{
			int u,v;
			scanf("%d%d",&u,&v);
			add_edge(u,v);
			add_edge(v,u);
		}
		for(int i=1;i<=n;i++)
		{
			if(!dfn[i])
			{
				tarjan(i);
			}
		}
		for(int i=1;i<=idx;i++)
		{
			if(!id[i])
			{
				dfs(i,0);
			}
		}
		init();
		int q;
		scanf("%d",&q);
		while(q--)
		{
			int S;
			int ans=0;
			scanf("%d",&S);
			for(int i=1;i<=S;i++)
			{
				scanf("%d",&a[i]);
			}
			sort(a+1,a+S+1,cmp);
			a[S+1]=a[1];
			for(int i=1;i<=S;i++)
			{
				int lca=LCA(a[i],a[i+1]);
				ans+=val[a[i]]+val[a[i+1]]-2*val[lca];
			}
			ans/=2;
			ans-=S;
			ans+=(LCA(a[1],a[S])<=n);
			printf("%d\n",ans);
		}
	}
	return 0;
}
2024/11/23 20:23
加载中...