求助虚树,MLE+TLE
查看原帖
求助虚树,MLE+TLE
127925
Kio_楼主2021/11/16 22:36

虽然感觉绝对是弱智错误但我真调不出来了

参考的是这篇题解的写法

提交记录

#include<cstdio>
#include<cstring>
#include<bitset>
#include<algorithm>
#include<vector>

using namespace std;

typedef long long ll;

const int N = 2.5e5+10;

inline bool isd(int c){return '0'<=c&&c<='9';}
int read(){
	int num,c,f=1;
	for(;!isd(c=getchar());f=c);
	for(num=c^48;isd(c=getchar());(num*=10)+=c^48);
	return f^45?num:-num;
}

struct edge{
	int v,w,nxt;
	edge(int v=0,int w=0,int nxt=0):v(v),w(w),nxt(nxt){}
}e[N<<1], ei[N]; int head[N], headi[N], cnt, cnti;//ei[]为虚树 

inline void addline(int u,int v,int w){
	e[++cnt] = edge(v,w,head[u]), head[u] = cnt;
}
inline void addlinei(int u,int v,int w){
	ei[++cnti] = edge(v,w,headi[u]), headi[u] = cnti;
}

inline int min(int a,int b){return a<b?a:b;}
int n,m,q,k,fa[N][22],minw[N][22],dep[N],dfn[N],df,d;
int sta[N], K[N], tp;
ll f[N];
bitset<N> pd; //判是否是关键点 

void dfs(int x){
	dfn[x] = ++df;
	for(int i=head[x];i;i=e[i].nxt){
		int y = e[i].v;
		if(y == fa[x][0]) continue;
		fa[y][0] = x;
		minw[y][0] = e[i].w, dep[y] = dep[x] + 1;
		dfs(y);
	}
}
int lca(int x,int y){
	d=2e9;
	if(dep[x] < dep[y]) x^=y^=x^=y;	
	for(int i=19;i>=0;i--) if(dep[fa[x][i]] >= dep[y]) d = min(d,minw[x][i]), x = fa[x][i];
	if(x==y) return y;
	for(int i=19;i>=0;i--) if(fa[x][i] != fa[y][i]) d = min(d,min(minw[x][i],minw[y][i])), x=fa[x][i], y=fa[y][i];
	return fa[x][0];
}

inline bool cmp(int a, int b){return dfn[a] < dfn[b];}

void build(){
	sort(K+1,K+k+1,cmp);
	sta[tp=1] = 1;
	for(int i=1;i<=k;i++){
		headi[K[i]] = 0;
		int Lca = lca(K[i], sta[tp]);
		if(Lca != sta[tp]){
			while(tp>1 && dfn[sta[tp-1]] >= dfn[Lca]){
				lca(sta[tp-1],sta[tp]);
				addlinei(sta[tp-1],sta[tp],d), tp--;
			}
			if(Lca != sta[tp]){
				lca(Lca,sta[tp]);
				addlinei(Lca,sta[tp],d), sta[tp] = Lca;
			}
		}
		sta[++tp] = K[i];
	}
	while(tp>1){
		lca(sta[tp-1],sta[tp]);
		addlinei(sta[tp-1], sta[tp], d);
		tp--;
	}
}

void dp(int x){
	f[x] = 0;
	for(int i=headi[x];i;i=ei[i].nxt){
	//	printf("x: %d\n",x);
		int y = ei[i].v;
		if(pd[y]) f[x] += ei[i].w;
		else dp(y), f[x] += min(f[y],ei[i].w);
	}
} 
int main(){
	memset(minw,0x3f,sizeof(minw));
	n=read();
	for(int i=1;i<n;i++){
		int u=read(),v=read(),w=read();
		addline(u,v,w), addline(v,u,w);
	}
	dep[1] = 1;
	dfs(1);
	for(int j=1;j<=19;j++)
		for(int i=1;i<=n;i++){
			fa[i][j] = fa[fa[i][j-1]][j-1];
			minw[i][j] = min(minw[i][j-1],minw[fa[i][j-1]][j-1]);
		}
		
	m=read();
	while(m--){
		k=read(), cnti=0;
		headi[1]=0;
		for(int i=1;i<=k;i++) K[i]=read(), pd[K[i]]=1;
		build();
		dp(1);
		printf("%lld\n",f[1]);
		for(int i=1;i<=k;i++) pd[K[i]] = 0;
	}
	return 0;
}

谢谢dalao;w;

2021/11/16 22:36
加载中...