警示后人 如果你20pts
查看原帖
警示后人 如果你20pts
606278
封禁用户楼主2024/12/30 22:36
// 2<=n<=2.5e5 1<=m<=5e5 sum[ki]<=5e5 1<=ki<n hi!=1 1<=u,v<=n 1<=w<=1e5
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int MAXN=4e6+5;

int cnt=0;
int f[MAXN][35],dep[MAXN],dep1[MAXN],dfn[MAXN],st[MAXN],siz=0,maxn=0,minn=1e9,numm,signum[MAXN],mx[MAXN],mn[MAXN],sum;
vector<int> e[MAXN],e1[MAXN];
vector<pair<int,int> > e2[MAXN];
vector<pair<int,int> > v;
bool vis1[MAXN];

void dfs(int id,int fa){
	dfn[id]=++cnt;
	f[id][0]=fa;
	if (!fa) dep[id]=0;
	else dep[id]=dep[fa]+1;
	for (int i=1;i<=30;i++)
		f[id][i]=f[f[id][i-1]][i-1];
	for (int i:e[id]) if (i!=fa and i!=id) dfs(i,id);
}

void dfs1(int id,int fa,int dept){
	dep1[id]=dept;
	for (auto i:e2[id]) if (i.first!=fa and i.first!=id) dfs1(i.first,id,min(dept,i.second));
}

pair<int,int> lca(int x,int y){
	if (dep[x]<dep[y]) swap(x,y);
	int sum=0;
	for (int i=30;i>=0;i--)
		if (dep[f[x][i]]>=dep[y] and f[x][i])
			sum+=(1<<i),x=f[x][i];
			
	if (x==y) return {x,sum};
	
	for (int i=30;i>=0;i--)
		if (f[x][i]!=f[y][i] and f[x][i] and f[y][i])
			sum+=(1<<(i+1)),x=f[x][i],y=f[y][i];
	
	return {f[x][0],sum+2};
}

int func(int id,int fa){
	if (vis1[id]){
		for (int i:e1[id]) if (i!=id and i!=fa) func(i,id);
		return dep1[id];
	}
	else{
		int sum=0;
		for (int i:e1[id]) if (i!=id and i!=fa) sum+=func(i,id);
		return min(dep1[id],sum);
	}
	vis1[id]=0;
}

signed main(){
	int n;
	scanf("%lld",&n);
	for (int i=1;i<n;i++){
		int a,b,w;
		scanf("%lld %lld %lld",&a,&b,&w);
		e[a].push_back(b);
		e[b].push_back(a);
		e2[a].push_back({b,w});
		e2[b].push_back({a,w});
	}
	dfs1(1,0,1e18);
	dfs(1,0);
	int q;
	scanf("%lld",&q);
	for (int i=1;i<=q;i++){
		v.clear();
		scanf("%lld",&numm);
		for (int j=1;j<=numm;j++){
			int tmp;
			scanf("%lld",&tmp);
			v.push_back({dfn[tmp],tmp});
			vis1[tmp]=1;
		}
		sort(v.begin(),v.end());
		st[siz=1]=1;
		e1[1].clear();
		for (auto j:v){
			int k=j.second;
			if (k==1)
				continue;
			int z=lca(k,st[siz]).first;
			if (z!=st[siz]){
				while (dfn[z]<dfn[st[siz-1]]){
					int u=st[siz],v=st[siz-1];
					e1[u].push_back(v);
					e1[v].push_back(u);
					siz--;
				}
				if (dfn[z]>dfn[st[siz-1]]){
					int u=st[siz],v=z;
					e1[z].clear();
					e1[u].push_back(v);
					e1[v].push_back(u);
					st[siz]=z;
				}
				else{
					int u=z,v=st[siz--];
					e1[u].push_back(v);
					e1[v].push_back(u);
				}
			}
			e1[k].clear();
			st[++siz]=k;
		}
		for (int j=1;j<siz;j++){
			int u=st[j],v=st[j+1];
			e1[u].push_back(v);
			e1[v].push_back(u);
		}
		printf("%lld\n",func(st[1],0));
	}
	
	return 0;
} 

提交记录

请看dp部分(func函数),这里不能直接返回值,需用ans记录答案在清空后再进行return

哪个傻子会在这调1h?

2024/12/30 22:36
加载中...