RT,敲了一份虽然AC但是样例没过的代码……
在oj上也是这样……
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
inline ll read(){
ll k=0;bool f=1;char ch=getchar();
while(!isdigit(ch)){if(ch=='-')f=0;ch=getchar();}
while(isdigit(ch)){k=(k<<1)+(k<<3)+(ch^48);ch=getchar();}
return f?k:~k+1;
}
const int N=1e5+2,M=3*N;
struct Edge1{
int u,v;ll w;
}E[M];
struct Edge2{
int v,next;ll w;
}e[M*2];
int h[N],tot;
inline void Add(int u,int v,int w){
e[++tot].v=v;
e[tot].w=w;
e[tot].next=h[u];
h[u]=tot;
}
int n,k,m,f[N];
int find(int x){
return f[x]==x?x:f[x]=find(f[x]);
}
bool comp(const Edge1 x,const Edge1 y){
return x.w<y.w;
}
bool vis[M];
int dep[N],F[N][20];
ll ans,s[N][20][2];
inline void Kruskal(){
sort(E+1,E+m+1,comp);
for(int i=1;i<=n;i++)f[i]=i;
for(int i=1;i<=m;i++) {
int u=E[i].u,v=E[i].v;
if(find(u)!=find(v)) {
int w=E[i].w;
ans+=w;vis[i]=1;
f[find(u)]=find(v);
Add(u,v,w);Add(v,u,w);
}
}
}
void Lcapre(int x){
dep[x]=dep[F[x][0]]+1;
for(int i=1,ed=(int)log2(dep[x]-1);i<=ed;i++) {
F[x][i]=F[F[x][i-1]][i-1];
s[x][i][0]=max(s[x][i-1][0],s[F[x][i-1]][i-1][0]);
if(s[x][i-1][0]==s[F[x][i-1]][i-1][0])
s[x][i][1]=max(s[x][i-1][1],s[F[x][i-1]][i-1][1]);
else
if(s[x][i-1][0]>s[F[x][i-1]][i-1][0])
s[x][i][1]=max(s[x][i-1][1],s[F[x][i-1]][i-1][0]);
else s[x][i][1]=max(s[x][i-1][0],s[F[x][i-1]][i-1][1]);
}
for(int i=h[x];i;i=e[i].next) {
if(F[x][0]==e[i].v)continue;
F[e[i].v][0]=x;
s[e[i].v][0][0]=e[i].w;
Lcapre(e[i].v);
}
}
inline void jump(ll &a1,ll &a2,int &x,int i){
a2=s[x][i][0]>a1?a1:a2;
a1=max(a1,s[x][i][0]);
x=F[x][i];
}
inline ll Lca(int x,int y,ll w){
if(dep[x]<dep[y]) swap(x,y);
ll an1=0,an2=0;
for(int i=(int)log2(dep[x]-1);i>=0;i--) {
if(dep[F[x][i]]>=dep[y]) jump(an1,an2,x,i);
}
for(int i=(int)log2(dep[x]-1);i>=0;i--) {
if(F[x][i]!=F[y][i]) jump(an1,an2,x,i),jump(an1,an2,y,i);
}
if(x!=y) jump(an1,an2,x,0),jump(an1,an2,y,0);
return w==an1?w-an2:w-an1;
}
inline void Answer(){
ll plus=LONG_LONG_MAX;
for(int i=1;i<=m;i++) {
if(vis[i]) continue;
plus=min(plus,Lca(E[i].u,E[i].v,E[i].w));
}
printf("%lld",ans+plus);
}
int main(){
n=read();
k=read();
for(int i=1;i<=k;i++)
{
int u=read(),v=read(),w=read();
if(u!=v) E[++m]=(Edge1){u,v,w};
}
Kruskal();
Lcapre(1);
Answer();
return 0;
}
求助错在哪里?(太玄学了)