救啊
天天MLE,空间都减小了快一倍了
甚至有的都RE与MLE同时出现
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<algorithm>
#define INF 123123123123123
#define num ch-'0'
#define N 100010
#define maxm 900010
#define NN 333333
using namespace std;
int n,m,x,y,lg[N],fa[N],tot,head[N],depth[N];
int z;
long long ans;
int f[N][19];//f[i][j]表示从i点向上跳2^j步到达的点
long long maxi[N][19],mini[N][19];//maxi[i][j]表示从i点向上跳2^j步能到达的最大距离,mini表示次大距离
bool B[NN];
inline void get(int &res){
char ch;bool flag=0;
while(!isdigit(ch=getchar()))
(ch=='-')&&(flag=true);
for(res=num;isdigit(ch=getchar());res=res*10+num);
(flag)&&(res=-res);
}
struct edge{
int fr,to,nxt;
int dis;
}e[NN];
inline void add(int fr,int to,int dis){
e[++tot].to=to;
e[tot].dis=dis;
e[tot].fr=fr;
e[tot].nxt=head[fr];
head[fr]=tot;
}
inline int Getf(int x){
if(fa[x]==x) return x;
return fa[x]=Getf(fa[x]);
}
inline void hb(int x,int y){
x=Getf(x);
y=Getf(y);
if(x!=y) fa[y]=x;
}
inline bool pd(int x,int y){
x=Getf(x);
y=Getf(y);
if(x==y) return true;
return false;
}
inline int cmp(edge a,edge b){
return a.dis<b.dis;
}
inline void caq(){
for(int i=1;i<=18;++i)
for(int j=1;j<=n;++j){
f[j][i]=f[f[j][i-1]][i-1];//
maxi[j][i]=max(maxi[j][i-1],maxi[f[j][i-1]][i-1]);
mini[j][i]=max(mini[j][i-1],mini[f[j][i-1]][i-1]);
if(maxi[j][i-1]>maxi[f[j][i-1]][i-1]) mini[j][i]=max(mini[j][i],maxi[f[j][i-1]][i-1]);
else if(maxi[j][i-1]<maxi[f[j][i-1]][i-1]) mini[j][i]=max(mini[j][i],maxi[j][i-1]);
//如果当前最大的找到一个更大的,那当前最大的就是次大的
}
}
inline void dfs(int now,int p){//此函数作为倍增求LCA的预处理函数,预处理出每个点的父亲结点和深度,以及最大和次大的初始值
//p是now的父亲
f[now][0]=p;//now往上跳一步到达p点,更新父亲结点
// for(long long i=1;(1<<i)<=depth[now];i++){
//// for(long long i=1;i<=18;i++){//根据数据来把2的多少次方都枚举一遍
// f[now][i]=f[f[now][i-1]][i-1];//从now点往上跳2^i步 也就是 往上跳2^(i-1)步后再往上跳2^(i-1)步
// }
for(int i=head[now];i;i=e[i].nxt){
int to=e[i].to;
if(to==f[now][0]) continue;//如果to是now的父亲,那么他已经被访问过了,不能回溯了
depth[now]=depth[p]+1;//更新深度
//因为所有连到now点的点中,除了他的父亲点已经确定了深度和父亲结点,其他的点都没有确定,所以可以作为now点的儿子
maxi[to][0]=e[i].dis;
mini[to][0]=-INF;//
dfs(to,now);
}
}
inline int lca(int x,int y){
if(depth[x]<depth[y]) swap(x,y);
// while(depth[x]>depth[y])
// x=f[x][lg[depth[x]-depth[y]]-1];
for(int i=18;i>=0;--i)
if(depth[f[x][i]]>=depth[y])
x=f[x][i];
if(x==y) return x;
if(x!=y){
for(int i=18;i>=0;--i)
if(f[x][i]!=f[y][i]){
x=f[x][i];
y=f[y][i];
}
x=f[x][0];
}
return x;
}
inline int get_max(int u,int v,int maxx)
{
long long Ans=-INF;
for(int i=18;i>=0;--i)
{
if(depth[f[u][i]]>=depth[v])
{
if(maxx!=maxi[u][i]) Ans=max(Ans,maxi[u][i]);
else Ans=max(Ans,mini[u][i]);
u=f[u][i];
}
}
return Ans;
}
int main(){
scanf("%d%d",&n,&m);
for(int i=1;i<=m;i++){
scanf("%d%d%d",&x,&y,&z);
add(x,y,z);
// add(y,x,z);
}
for(int i=1;i<=n;i++){
// lg[i]= lg[i-1]+(1<<lg[i-1]==i);//手动处理lg函数,我也看不懂,背过就完了
lg[i]=lg[i>>1]+1;
fa[i]=i;
}
sort(e+1,e+m+1,cmp);
for(int i=1;i<=m;i++){
if(pd(e[i].fr,e[i].to)) continue;
hb(e[i].fr,e[i].to);
ans+=e[i].dis;
B[i]=true;
}
// cout<<ans<<" ";
mini[1][0]=-INF;
depth[1]=1;
dfs(1,-1);
caq();
long long an=INF;
for(long long i=1;i<=m;++i){
if(!B[i]){
// if(!pd(e[i].fr,e[i].to)){
int u=e[i].fr;
int v=e[i].to;
long long d=e[i].dis;
long long maxu=get_max(u,lca(u,v),d);
long long maxv=get_max(v,lca(u,v),d);
an=min(an,ans-max(maxu,maxv)+d);
}
// cout<<e[i].fr<<" "<<e[i].to<<" "<<e[i].dis<<endl;
// cout<<lca(e[i].fr,e[i].to)<<" "<<get_max(e[i].fr,lca(e[i].fr,e[i].to),e[i].dis)<<" "<<get_max(e[i].to,lca(e[i].fr,e[i].to),e[i].dis)<<endl;
}
printf("%lld",an);
return 0;
}