P2495 [SDOI2011] 消耗战 的代码

P2495 [SDOI2011] 消耗战 的代码

#include<bits/stdc++.h>
using namespace std;
#define int long long 
const int maxn=5*1e5;
const int maxm=20;
const int inf=LLONG_MAX;
struct Edge{int u,v,w,nxt;};
struct Graph{;
	Edge e[maxn+5];
	int hd[maxn+5],et;
	inline void Init(){
		et=0;
		memset(hd,-1,sizeof(hd));
		memset(e,-1,sizeof(e));
	}
	inline void Adde(int u,int v,int w){
		e[et].u=u,e[et].v=v,e[et].w=w,e[et].nxt=hd[u],hd[u]=et++;
	}
};
int n,m,K;
Graph A,B;
int fa[maxn+5][maxm+5];
int dis[maxn+5][maxm+5];
int dfn[maxn+5],tt;
int de[maxn+5];
int p[maxn+5];
bool ip[maxn+5];
int f[maxn+5];
void DfsA(int u,int F){
	int v,w;
	dfn[u]=++tt;
	for(int i=A.hd[u];~i;i=A.e[i].nxt){
		v=A.e[i].v,w=A.e[i].w;
		if(v==F) continue;
		fa[v][0]=u;
		dis[v][0]=w;
		de[v]=de[u]+1;
		DfsA(v,u);
	}
}
inline void Init(){
	for(int j=1;j<=maxm;j++){
		for(int i=1;i<=n;i++){
			fa[i][j]=fa[fa[i][j-1]][j-1];
			dis[i][j]=min(dis[i][j-1],dis[fa[i][j-1]][j-1]);
		}
	}
}
inline int Lca(int x,int y){
	if(de[x]<de[y]) swap(x,y);
	for(int j=maxm;j>=0;j--)
		if(de[fa[x][j]]>=de[y])
			x=fa[x][j];
	if(x==y) return x;
	for(int j=maxm;j>=0;j--)
		if(fa[x][j]!=fa[y][j])
			x=fa[x][j],y=fa[y][j];
	return fa[x][0];
}
inline int Dis(int x,int y){
	int res=inf;
	if(de[x]<de[y]) swap(x,y);
	for(int j=maxm;j>=0;j--){
		if(de[fa[x][j]]>=de[y]){
			res=min(res,dis[x][j]);
			x=fa[x][j];
		}
	}
	return res;
}
void DfsB(int u,int F,int V){
	int v,w,sum=0;
	if(ip[u]){
		f[u]=V;
		return;
	}
	for(int i=B.hd[u];~i;i=B.e[i].nxt){
		v=B.e[i].v,w=B.e[i].w;
		DfsB(v,u,w);
		sum+=f[v];
	}
	f[u]=min(V,sum);
}
inline bool Cmp(int x,int y){return dfn[x]<dfn[y];}
signed main(){
	int u,v,w;
	A.Init(),B.Init();
	scanf("%lld",&n);
	for(int i=1;i<n;i++){
		scanf("%lld%lld%lld",&u,&v,&w);
		A.Adde(u,v,w),A.Adde(v,u,w);
	}
	de[1]=1;
	DfsA(1,0);
	Init();
	scanf("%lld",&m);
	while(m--){
		scanf("%lld",&K);
		for(int i=1;i<=K;i++){
			scanf("%lld",&p[i]);
			ip[p[i]]=1;
		}
		p[++K]=1;
		sort(p+1,p+K+1,Cmp);
		w=K;
		for(int i=1;i<w;i++)
			p[++K]=Lca(p[i],p[i+1]);
		sort(p+1,p+K+1,Cmp);
		K=unique(p+1,p+K+1)-p-1;
		for(int i=1;i<K;i++){
			u=Lca(p[i],p[i+1]);
			v=p[i+1];
			w=Dis(u,v);
			B.Adde(u,v,w);
		}
		DfsB(1,0,inf);
		printf("%lld\n",f[1]);
		B.et=0;
		for(int i=1;i<=K;i++){
			ip[p[i]]=0;
			B.hd[p[i]]=-1;
		}
	}
	return 0;
}
posted @ 2024-05-16 22:10  DeepSeaSpray  阅读(2)  评论(0编辑  收藏  举报