河童重工 淀粉质套淀粉质求调 只有sub4全对 悬赏5关
查看原帖
河童重工 淀粉质套淀粉质求调 只有sub4全对 悬赏5关
556975
PNNNN楼主2024/8/15 17:13
#include<bits/stdc++.h>
using namespace std;

int n,dis[100005],val[100005],ans;

struct EDGE{
	int x,y,w;
};vector <EDGE> edge;

inline bool Tuesday(EDGE A,EDGE B){return A.w<B.w;}

struct DSU{
	int f[100005];
	inline void init(){for(int i=1;i<=n;i++)f[i]=i;return;}
	inline int find(int x){
		return f[x]==x?x:f[x]=find(f[x]);
	}
}dsu;

struct DFZ{
	int crt,siz[100005],vis[100005],sz;
	struct line{
		int y,w;
	};vector <line> to[100005];
	inline void rana(int x,int last){
		siz[x]=1;int maxn=0;
		for(auto [y,w]:to[x]){
			if(vis[y]||y==last)continue;
			rana(y,x);if(crt)return;
			siz[x]+=siz[y],maxn=max(maxn,siz[y]);
		}maxn=max(maxn,sz-siz[x]);
		if(maxn<=sz/2){
			crt=x,siz[last]=sz-siz[x];
		}return;
	}
	inline void find(int x,int last){
		crt=0,rana(x,last);return;
	}
}T1,T2;

struct SLPF{
	int dep[100005],fa[100005],siz[100005],mxs[100005],top[100005],dfn[100005],cnt;
	inline void dfs1(int x,int last){
		dep[x]=dep[last]+1,fa[x]=last,siz[x]=1;
		for(auto [y,w]:T2.to[x]){
			if(y==last)continue;
			dis[y]=dis[x]+w,dfs1(y,x),siz[x]+=siz[y];
			if(siz[y]>siz[mxs[x]])mxs[x]=y;
		}return;
	}
	inline void dfs2(int x,int last){
		dfn[x]=++cnt,top[x]=last;
		if(!mxs[x])return;dfs2(mxs[x],last);
		for(auto [y,w]:T2.to[x]){
			if(y!=fa[x]&&y!=mxs[x])dfs2(y,y);
		}return;
	}
	inline int lca(int x,int y){
		while(top[x]!=top[y]){
			if(dep[top[x]]<dep[top[y]])swap(x,y);
			x=fa[top[x]];
		}if(dep[x]>dep[y])swap(x,y);return x;
	}
}sp;

inline void init(){
	sp.dfs1(1,0),sp.dfs2(1,1);
	for(int i=1;i<=n;i++){
		T2.to[i].clear();
	}return;
}

vector <pair<int,int>> e;

inline void push(int x,int last,int dist){
	e.push_back({val[x]+dist,x});
	for(auto [y,w]:T2.to[x]){
		if(!T2.vis[y]&&y!=last)push(y,x,dist+w);
	}return;
}

inline void calc(int x){
	T2.vis[x]=1;
	e.clear(),push(x,0,0);
	sort(e.begin(),e.end());
	for(int i=1;i<e.size();i++){
		edge.push_back({e[0].second,e[i].second,e[0].first+e[i].first});
	}
	for(auto [y,w]:T2.to[x]){
		if(T2.vis[y])continue;
		T2.sz=T2.siz[y],T2.find(y,x),calc(T2.crt);
	}return;
}

vector <int> vec;

int tmp[200005];

inline bool cmp(int x,int y){return sp.dfn[x]<sp.dfn[y];}

inline void build(){
	sort(vec.begin(),vec.end(),cmp),tmp[0]=0;
	for(int i=0;i<vec.size();i++){
		tmp[++tmp[0]]=vec[i];
		if(i+1<vec.size())tmp[++tmp[0]]=sp.lca(vec[i],vec[i+1]); 
	}sort(tmp+1,tmp+1+tmp[0],cmp);
	tmp[0]=unique(tmp+1,tmp+1+tmp[0])-tmp-1;
	for(int i=1;i<tmp[0];i++){
		int LCA=sp.lca(tmp[i],tmp[i+1]);
		T2.to[LCA].push_back({tmp[i+1],dis[tmp[i+1]]-dis[LCA]});
		T2.to[tmp[i+1]].push_back({LCA,dis[tmp[i+1]]-dis[LCA]});
	}
	T2.sz=tmp[0],T2.find(tmp[1],0),calc(T2.crt);
	T2.to[tmp[1]].clear();
	for(int i=1;i<tmp[0];i++){
		T2.vis[tmp[i]]=T2.vis[tmp[i+1]]=0;
		T2.to[sp.lca(tmp[i],tmp[i+1])].clear();
		T2.to[tmp[i+1]].clear();
	}return;
}

inline void insert(int x,int last,int dist){
	vec.push_back(x),val[x]=dist;
	for(auto [y,w]:T1.to[x]){
		if(!T1.vis[y]&&y!=last)insert(y,x,dist+w);
	}return;
}

inline void solve(int x){
	T1.vis[x]=1,vec={x},val[x]=0;
	for(auto [y,w]:T1.to[x]){
		if(!T1.vis[y])insert(y,x,w);
	}build();
	for(auto [y,w]:T1.to[x]){
		if(T1.vis[y])continue;
		T1.sz=T1.siz[y],T1.find(y,x),solve(T1.crt);
	}return;
}

inline int read(){
	register int x(0),t(0);
	static char ch=getchar();
	while(!isdigit(ch)){t|=(ch=='-');ch=getchar();}
	while(isdigit(ch)){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}
	return t?-x:x;
}

signed main(){
	n=read();
	for(int i=1;i<n;i++){
		int x=read(),y=read(),w=read();
		T1.to[x].push_back({y,w}),T1.to[y].push_back({x,w});
	}
	for(int i=1;i<n;i++){
		int x=read(),y=read(),w=read();
		T2.to[x].push_back({y,w}),T2.to[y].push_back({x,w});
	}
	init(),dsu.init();
	T1.sz=n,T1.find(1,0),solve(T1.crt);
	sort(edge.begin(),edge.end(),Tuesday);
	for(auto [x,y,w]:edge){
		if(dsu.find(x)!=dsu.find(y)){
			dsu.f[dsu.find(x)]=dsu.find(y),ans+=w;
		}
	}
	cout<<ans;
	return 0;
}

rt

2024/8/15 17:13
加载中...