在洛谷上过了的代码
#include<iostream>
#include<cmath>
#include<cstring>
#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<queue>
using namespace std;
typedef long long ll;
const ll N=3e5+5,M=9e5+5,INF=1e15;
ll n,m,ans=0,d[N],f[N][30],D=18,ans2=INF;
ll fa[N];
ll mi[30],maxn[N][30],tmax[N][30];
bool v[M];
struct edge{
ll x,y,z;
ll ne;
}g[N<<1],e[N];
ll idx=0,h[N];
void double_add(ll x,ll y,ll z){
g[++idx].x=x,g[idx].y=y,g[idx].z=z,g[idx].ne=h[x],h[x]=idx;
g[++idx].x=y,g[idx].y=x,g[idx].z=z,g[idx].ne=h[y],h[y]=idx;
return ;
}
bool cmp(edge x,edge y){
return x.z<y.z;
}
ll read(){
ll x=0;
char ch=getchar();
while(ch<'0'||ch>'9') ch=getchar();
while(ch>='0'&&ch<='9') x=x*10+(ch^48),ch=getchar();
return x;
}
ll Get(ll x){
if(fa[x]==x) return x;
return fa[x]=Get(fa[x]);
}
void dfs(ll x,ll f_,ll dep){ //倍增预处理
d[x]=dep;
for(ll i=1;;i++){
if(d[x]-mi[i]<0) break;
f[x][i]=f[f[x][i-1]][i-1];
ll k=f[x][i-1];
maxn[x][i]=max(maxn[x][i-1],maxn[k][i-1]);
if(maxn[x][i-1]==maxn[k][i - 1])
tmax[x][i]=max(tmax[x][i - 1],tmax[k][i - 1]);
else
tmax[x][i]=max(min(maxn[x][i-1],maxn[k][i-1]),
max(tmax[x][i-1],tmax[k][i-1]));
}
for(ll i=h[x];i!=-1;i=g[i].ne){
ll y=g[i].y;
if(y!=f_){
f[y][0]=x;
maxn[y][0]=g[i].z;
tmax[y][0]=-1;
dfs(y,x,dep+1);
}
}
return ;
}
ll LCA(ll x,ll y){
if(d[x]<d[y]) swap(x,y);
ll k=d[x]-d[y];
for(ll i=0;i<=D;++i)
if(k>>i&1) x=f[x][i];
if(x==y) return x;
for(ll i=D;i>=0;--i)
if(f[x][i]!=f[y][i]) x=f[x][i],y=f[y][i];
return f[x][0];
}
void Work(ll x,ll y,ll z){
ll m1=0,m2=0,k=d[x]-d[y];
for(ll i=0;i<=D;++i){
if(k>>i&1){
m2=max(m2,tmax[x][i]);
if(maxn[x][i]>m1){
m2=max(m1,m2);
m1=maxn[x][i];
}
}
}
if(m1==z) ans2=min(ans2,z-m2);
else ans2=min(ans2,z-m1);
return ;
}
void Kru(){
sort(e+1,e+1+m,cmp);
for(ll i=1;i<=n;++i) fa[i]=i,v[i]=false;
ll js=0;
for(ll i=1;js<n-1;++i){
ll x=Get(e[i].x);
ll y=Get(e[i].y);
if(x==y) continue;
fa[x]=y;
js++;
ans+=e[i].z;
v[i]=true;
double_add(e[i].x,e[i].y,e[i].z);
}
return ;
}
int main(){
n=read();m=read();
for(ll i=1;i<=n;++i) h[i]=-1;
mi[0]=1;
for(ll i=1;i<=D;++i) mi[i]=mi[i-1]<<1;
for(ll i=1;i<=m;++i){
e[i].x=read();e[i].y=read();e[i].z=read();
}
Kru();
dfs(1,0,1);
for(ll i=1;i<=m;++i){
if(!v[i]){
ll x=e[i].x,y=e[i].y;
ll l=LCA(x,y);
Work(x,l,e[i].z);
Work(y,l,e[i].z);
}
}
printf("%d",ans+ans2);
return 0;
}
交loj上WA一个点 )
求大佬解惑