#include<bits/stdc++.h>
using namespace std;
using i64=long long;
using u64=unsigned long long;
constexpr int inf=1e9;
struct data{
int u,v,w;
};
struct stu{
int v,w;
};
struct DSU{
vector<int> f,siz;
DSU(){};
DSU(int n){
inite(n);
};
void inite(int n){
f.resize(n);
iota(f.begin(),f.end(),0);
siz.assign(n,1);
}
int find(int x){
while(f[x]!=x){
x=f[x]=f[f[x]];
}
return x;
}
bool merge(int x,int y){
x=find(x),y=find(y);
if(x==y) return false;
else{
f[y]=x;
siz[x]+=siz[y];
return true;
}
}
bool same(int x,int y){
return (find(x)==find(y));
}
};
int cmp(data x,data y){
return x.w<y.w;
}
//严格次大的生成树
//先生成一颗最小生成树 然后枚举选取没有被选中的边 加边,此时会有一个环
//树上倍增LCA维护最大值 以及次大值 然后删除 次大值
vector<stu> edge[100005];
void solve(){
int n,m;
cin>>n>>m;
vector<data> a(m+1);
vector<int> vis(m+1);
i64 ans=0;
vector<vector<int>> f(n+1,vector<int>(32)),mx1(n+1,vector<int>(32)),mx2(n+1,vector<int>(32,-inf));
vector<int> dep(n+1);
DSU g(n+1);
for(int i=1;i<=m;++i){
cin>>a[i].u>>a[i].v>>a[i].w;
}
int cnt=0;
auto kruskal =[&]()->void {
sort(a.begin()+1,a.end(),cmp);
for(int i=1;i<=m;++i){
if(!g.same(a[i].u,a[i].v)){
g.merge(a[i].u,a[i].v);
edge[a[i].u].push_back({a[i].v,a[i].w});
edge[a[i].v].push_back({a[i].u,a[i].w});
ans+=a[i].w;
cnt++;
vis[i]=1;
if(cnt>=n-1) return;
}
}
};
auto dfs=[&](auto& self,int rt,int fno,int w)->void {
dep[rt]=dep[fno]+1;
f[rt][0]=fno,mx1[rt][0]=w,mx2[rt][0]=-inf;
for(int i=1;i<=31;++i){
mx1[rt][i]=max(mx1[f[rt][i-1]][i-1],mx1[rt][i-1]);
mx2[rt][i]=max(max(mx2[f[rt][i-1]][i-1],mx2[rt][i-1]), mx1[f[rt][i-1]][i-1] == mx1[rt][i-1] ? 0 : min(mx1[f[rt][i-1]][i-1],mx1[rt][i-1]));
f[rt][i]=f[f[rt][i-1]][i-1];
}
for(auto p: edge[rt]){
if(p.v!=fno){
self(self,p.v,rt,p.w);
}
}
};
//返回次大值
auto LCA=[&](int x,int y,int z)->int {
int ans=0;
if(dep[x]>dep[y]) swap(x,y);
int tem=dep[y]-dep[x];
for(int i=0;i<=tem && tem;tem>>=1,i++){
if(tem&1){
ans= max(ans,mx1[y][i]==z ? mx2[y][i] : mx1[y][i]);
y=f[y][i];
}
}
if(x==y) return ans;
for(int i=30;i>=0 && x!=y;--i){
if(f[x][i] != f[y][i]){
ans=max(ans,max(mx1[x][i],mx1[y][i]) == z ? max(mx2[x][i],mx2[y][i]) : max(mx1[x][i],mx1[y][i]));
x=f[x][i];
y=f[y][i];
}
}
return max(ans,max(mx1[x][0],mx1[y][0]) == z ? max(mx2[x][0],mx2[y][0]) : max(mx1[x][0],mx1[y][0])); ;
};
kruskal();
for(int i=1;i<=n;++i){
if(!dep[i])
dfs(dfs,i,0,0);
}
i64 res=inf;
i64 tem=0;
for(int i=1;i<=m;++i){
if(!vis[i] && a[i].v!=a[i].u){
tem=LCA(a[i].u,a[i].v,a[i].w);
res=min(-tem+a[i].w,res);
//cout<<tem<<' '<<a[i].w<<'\n';
}
}
cout<<ans+res<<'\n';
}
int main(){
ios::sync_with_stdio(0);
cin.tie(0),cout.tie(0);
solve();
return 0;
}
感觉没有哪个爆了啊,为什么错了呢