我不会写次小生成树了?
查看原帖
我不会写次小生成树了?
483966
一粒夸克楼主2021/10/12 12:08

30 分,很离谱

#include<bits/stdc++.h>
using namespace std;
int n,m;
int dsu[100005];
int find(int x){
	return dsu[x]==x?x:dsu[x]=find(dsu[x]);
}
long long ans;
int ver[200005],ne[200005],head[200005],val[200005],cnt;
inline void link(int x,int y,int v){
	ver[++cnt]=y;
	ne[cnt]=head[x];
	head[x]=cnt;val[cnt]=v;
}
struct ST{
	int x[2];
	ST(){x[0]=x[1]=0;}
	inline ST operator +(ST b){
		if(x[0]>=b.x[0]){
			if(x[0]!=b.x[0])b.x[1]=b.x[0];b.x[0]=x[0];
			b.x[1]=max(b.x[1],x[1]);
		}
		else b.x[1]=max(b.x[1],x[0]);
		return b;
	}
}st[19][100005];
int fa[19][100005],dep[100005];
void dfs(int x,int fi){
	fa[0][x]=fi;dep[x]=dep[fi]+1;
	for(int i=head[x];i;i=ne[i]){
		int u=ver[i];
		if(u==fi)continue;
		st[0][u].x[0]=val[i];
		dfs(u,x);
	}
}
inline ST lca(int x,int y){
	ST res;
	if(dep[x]<dep[y])swap(x,y);
	for(int i=18;~i;i--){
		if(dep[fa[i][x]]>=dep[y]){
			res=res+st[i][x];x=fa[i][x];
		}
	}
	for(int i=18;~i;i--){
		if(fa[i][x]!=fa[i][y]){
			res=st[i][x]+st[i][y]+res;
			x=fa[i][x];y=fa[i][y];
		}
	}//cout<<x<<" "<<y<<"lca"<<st[0][x].x[0]<<" "<<st[0][y].x[0]<<endl;
	if(x!=y)res=st[0][x]+st[0][y]+res;
	return res;
}
struct node{
	int x,y,z;
	node(int _x,int _y,int _z){
		x=_x;y=_y;z=_z;
	}
	inline bool operator <(const node &b)const{
		return z<b.z;
	}
	inline bool check(){
		return find(x)!=find(y);
	}
	inline void merge(){
		dsu[find(x)]=find(y);ans+=z;link(x,y,z);link(y,x,z);
	}
};
vector<node> vec;
int main(){
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;i++)dsu[i]=i;
	for(int i=1;i<=m;i++){
		int x,y,z;
		scanf("%d%d%d",&x,&y,&z);
		vec.push_back(node(x,y,z));
	}
	sort(vec.begin(),vec.end());
	vector<node> tmp;
	for(auto x:vec){
		if(x.check())x.merge();
		else tmp.push_back(x);
	}
	dfs(1,1);int res=2e9;
	for(int i=1;i<19;i++){
		for(int j=1;j<=n;j++)st[i][j]=st[i-1][j]+st[i-1][fa[i-1][j]];
	}
	for(auto x:tmp){
		ST tp=lca(x.x,x.y);
		if(tp.x[0]!=x.z)res=min(res,x.z-tp.x[0]);
		else res=min(res,x.z-tp.x[1]);
//		cout<<x.x<<"-"<<x.y<<" "<<tp.x[0]<<" "<<tp.x[1]<<" "<<x.z<<endl;
	}
	printf("%lld",ans+res);


	return 0;
}

2021/10/12 12:08
加载中...