虚树求条
查看原帖
虚树求条
728778
hdkk楼主2024/7/22 20:20

有没有人救一下,只过了链的部分分

#include<bits/stdc++.h>
#define int long long
using namespace std;
int b[1000005],head[1000005],num,siz[1000005],son[1000005],tp[1000005],fa[1000005],dep[1000005],dfn[1000005],tim,siz1[1000005],sum,dp[1000005];
long long ans=0;
int ans1=1e9,ans2=-1e9;
struct edge{
	int to,next;
}g[2000005];
void addd(int u,int v)
{
	num++;
	g[num].to=v;
	g[num].next=head[u];

	head[u]=num;
}
void dfs(int u)
{
	siz[u]++;
	dfn[u]=++tim;
	for(int i=head[u];i;i=g[i].next){
		int v=g[i].to;
		if(v==fa[u]) continue;
		dep[v]=dep[u]+1;
		fa[v]=u;
		dfs(v);
		siz[u]+=siz[v];
		if(siz[v]>siz[son[u]]) son[u]=v;
	}
}
void dfs1(int u)
{
	if(son[fa[u]]==u) tp[u]=tp[fa[u]];
	else tp[u]=u;
	for(int i=head[u];i;i=g[i].next)
	{
		int v=g[i].to;
		if(v==fa[u]) continue;
		dfs1(v);
	}
}
int lca(int u,int v)
{
	while(tp[u]!=tp[v])
	{
		if(dep[tp[u]]>dep[tp[v]]) swap(u,v);
		v=fa[tp[v]];
	}
	if(dep[u]>dep[v]) swap(u,v);
	return u;
}
bool cmpp(int r1,int r2)
{
	return dfn[r1]<dfn[r2];
}
int sta[1000006],cnt,mx[1000005],mn[1000005];
void build(int n)
{
	num=0;
	head[1]=0;
	sta[cnt=1]=1;
	sort(b+1,b+1+n,cmpp);
	for(int i=1;i<=n;i++)
	{
		if(b[i]!=1)
		{
			int l=lca(b[i],sta[cnt]);
			if(l!=sta[cnt])
			{
				while(dfn[l]<dfn[sta[cnt-1]]) addd(sta[cnt-1],sta[cnt]),cnt--;
				if(dfn[l]>dfn[sta[cnt-1]]) addd(l,sta[cnt]),sta[cnt]=l,head[l]=0;
				else addd(l,sta[cnt]),cnt--;
			}
			sta[++cnt]=b[i],head[b[i]]=0;
		}
	}
	for(int i=1;i<cnt;i++) addd(sta[i],sta[i+1]);
}
bool vis[1000005];
void dfs2(int u)
{
	if(vis[u]) mx[u]=mn[u]=0,siz1[u]=1;
	else mx[u]=-1e9,mn[u]=1e9,siz1[u]=0;
	dp[u]=0; 
	for(int i=head[u];i;i=g[i].next)
	{
		int v=g[i].to;
		dfs2(v);
		int l=dep[v]-dep[u];
		ans+=(dp[u]+l*siz1[u])*siz1[v]+dp[v]*siz1[u];
		siz1[u]+=siz1[v],dp[u]+=dp[v]+l*siz1[v];
		ans1=min(ans1,mn[u]+mn[v]+l),ans2=max(ans2,mx[u]+mx[v]+l);
		mn[u]=min(mn[u],mn[v]+l),mx[u]=max(mx[u],mx[v]+l); 
	}
}
signed main()
{
	int n;
	cin>>n;
	int u,v;
	for(int i=1;i<n;i++) cin>>u>>v,addd(u,v),addd(v,u);
	dep[1]=1;
	dfs(1);
	dfs1(1);
	int q;
	cin>>q;
	while(q--)
	{
		int k;
		cin>>k;
		for(int i=1;i<=k;i++) cin>>b[i],vis[b[i]]=1;
		build(k);
		ans=0,ans1=1e9,ans2=-1e9;
		dfs2(1);
		cout<<ans<<' '<<ans1<<' '<<ans2<<endl;
		for(int i=1;i<=k;i++) vis[b[i]]=0;
	}
}
2024/7/22 20:20
加载中...