dfs预处理的时候光顾着处理最大值与次大值了,竟然忘记处理祖先值。。。
#include<bits/stdc++.h>
#define rep(i,l,r) for(int i=(l);i<=(r);i++)
#define per(i,r,l) for(int i=(r);i>=(l);i--)
#define random(l,r) ((l)+rand()%((r)-(l)+1))
using namespace std;
typedef unsigned long long ull;
typedef long long ll;
const int inf=1e9+10,N=1e6+1010,M=3e6+1010;
const double eps=1e-6;
struct edge{int a,b,w;}e[M];
ll ans;
int n,m,f[N],dif=inf;
int head[N],nxt[N*2],to[N*2],w[N*2],len;//边数只需开N*2就行了,因为只存生成树上的边。
bool used[M];
inline void addedge(int a,int b,int ww){ nxt[++len]=head[a]; head[a]=len; to[len]=b; w[len]=ww; }
bool compare(edge a,edge b){ return a.w<b.w;}
int getf(int v){ return f[v]==v?v:f[v]=getf(f[v]);}
inline void merge(int a,int b){ f[getf(b)]=getf(a);}
inline void Kruskal(){
rep(i,1,n) f[i]=i;
sort(e+1,e+1+m,compare);
rep(i,1,m){
int a=e[i].a,b=e[i].b,faa=getf(a),fab=getf(b);
if(faa==fab) continue;
ans+=e[i].w; merge(faa,fab); used[i]=true;
}
}
int dep[N],fa[N][21],da[N][21],cida[N][21];//da存储最大值,cida存储严格次大值
void update(int &zuida,int &cida,int a){
if(a>zuida){
cida=zuida;
zuida=a;
} else if((a<zuida)&&(a>cida)) cida=a;
}
void dfs(int v,int father,int dp,int dis){
fa[v][0]=father; dep[v]=dp; da[v][0]=dis;
rep(i,1,20){
fa[v][i]=fa[fa[v][i-1]][i-1];
int da1=da[v][i-1],cida1=cida[v][i-1];
int da2=da[fa[v][i-1]][i-1],cida2=cida[fa[v][i-1]][i-1];
update(da[v][i],cida[v][i],da1);
update(da[v][i],cida[v][i],da2);
update(da[v][i],cida[v][i],cida1);
update(da[v][i],cida[v][i],cida2);
}
for(int i=head[v];i!=0;i=nxt[i]){
if(to[i]!=father) dfs(to[i],v,dp+1,w[i]);
}
}
pair<int,int> dalu(int a,int b){//倍增求最大瓶颈路、次大瓶颈路
if(dep[a]<dep[b]) return dalu(b,a);
int zuida=0,nowcida=0;
//应该先更新信息再跳到父亲
per(i,20,0)
if(dep[fa[a][i]]>=dep[b]) {
update(zuida,nowcida,da[a][i]);
update(zuida,nowcida,cida[a][i]);
a=fa[a][i];
}
if(a==b) return make_pair(zuida,nowcida);
per(i,20,0) if(fa[a][i]!=fa[b][i]){
update(zuida,nowcida,da[a][i]);
update(zuida,nowcida,cida[a][i]);
update(zuida,nowcida,da[b][i]);
update(zuida,nowcida,cida[b][i]);
a=fa[a][i]; b=fa[b][i];
}
update(zuida,nowcida,da[a][0]);
update(zuida,nowcida,da[b][0]);
return make_pair(zuida,nowcida);
}
int main(){
ios::sync_with_stdio(false); cin.tie(0);
//freopen("input.in","r",stdin);
cin>>n>>m;
rep(i,1,m) cin>>e[i].a>>e[i].b>>e[i].w;
Kruskal();
rep(i,1,m) if(used[i]) addedge(e[i].a,e[i].b,e[i].w),addedge(e[i].b,e[i].a,e[i].w);//建树
dfs(1,1,1,0);//倍增预处理
rep(i,1,m){
if(used[i]) continue;
pair<int,int> ret=dalu(e[i].a,e[i].b);
if(e[i].w==ret.first) dif=min(dif,e[i].w-ret.second);
else dif=min(dif,e[i].w-ret.first);
}
//cout<<dif<<endl;
//cout<<ans<<endl;
cout<<ans+dif;
return 0;
}