比赛 2025暑期集训第8场 评测结果 AAAAAAAAAA
题目名称 次小生成树 最终得分 100
用户昵称 左清源 运行时间 0.438 s
代码语言 C++ 内存使用 16.78 MiB
提交时间 2025-08-13 08:39:07
显示代码纯文本
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e5+10,M=3e5+10;
const ll inf=1e18;
int n,m,f[N][20],ff[N],d[N];
struct node{int u,v,w,used;}e[M];
struct edge{int to,v;};
vector<edge>G[N];
struct Data{
	ll mx,mxs;
	void init(ll v){
		mx=v,mxs=-inf;
		return;
	}
}g[N][20];
Data operator + (const Data &a,const Data &b){
	Data c;
	if(a.mx==b.mx){
		c.mx=a.mx;
		c.mxs=max(a.mxs,b.mxs);
	}else if(a.mx>b.mx){
		c.mx=a.mx;
		c.mxs=max(a.mxs,b.mx);
	}else if(a.mx<b.mx){
		c.mx=b.mx;
		c.mxs=max(a.mx,b.mxs);
	}
	return c;
} 
ll ans,sum;
int found(int x){
	return ff[x]==x?x:ff[x]=found(ff[x]);
}
void add(int x,int y,int z){
	G[x].push_back(edge{y,z});
	G[y].push_back(edge{x,z});
}
bool cmp(node a,node b){
	return a.w<b.w;
}
void kruskal(){
	for(int i=1;i<=n;i++)ff[i]=i;
	sort(e+1,e+1+m,cmp);
	for(int i=1;i<=m;i++){
		int u=found(e[i].u);
		int v=found(e[i].v);
		if(u==v)continue;
		e[i].used=1,ff[u]=v;
		sum+=e[i].w;
		add(e[i].u,e[i].v,e[i].w);
	}
	return;
} 
void dfs(int x,int fa){
	f[x][0]=fa,d[x]=d[fa]+1;
	for(int i=1;i<=19;i++){
		f[x][i]=f[f[x][i-1]][i-1];
		g[x][i]=g[x][i-1]+g[f[x][i-1]][i-1];
	}
	for(auto e:G[x]){
		if(e.to==fa)continue;
		g[e.to][0].init(e.v);
		dfs(e.to,x);
	}
	return;
}
Data ask(int a,int b){
	Data res;res.init(-inf);
	if(d[a]<d[b])swap(a,b);
	for(int i=19;i>=0;i--){
		if(d[f[a][i]]>=d[b]){
			res=res+g[a][i];
			a=f[a][i];
		} 
	}
	if(a==b)return res;
	for(int i=19;i>=0;i--){
		if(f[a][i]!=f[b][i]){
			res=res+g[a][i];
			res=res+g[b][i];
			a=f[a][i],b=f[b][i];
		}
	}
	res=res+g[a][0];
	res=res+g[b][0];
	return res;
}
int main(){
	freopen("secmst.in","r",stdin);
	freopen("secmst.out","w",stdout);
	scanf("%d %d",&n,&m);
	for(int i=1,u,v,w;i<=m;i++){
		scanf("%d %d %d",&u,&v,&w);
		e[i]=node{u,v,w,0};
	}
	kruskal();
	dfs(1,0);
	ans=inf;
	for(int i=1;i<=m;i++){
		if(e[i].used)continue;
		Data tmp=ask(e[i].u,e[i].v);
		if(e[i].w==tmp.mx){
			if(tmp.mxs!=-inf)ans=min(ans,sum-tmp.mxs+e[i].w);
		}else{
			ans=min(ans,sum-tmp.mx+e[i].w);
		}
	}
	printf("%lld\n",ans);
	return 0;
}