非严格次小生成树
#include <bits/stdc++.h>
using namespace std;
#define ll long long
const int maxN=1005;
int vis[100005];
int n,m;
vector<pair<int,int>> e[maxN];
int dep[maxN],st[maxN][25],up[maxN][25];
int fa[maxN];
int find(int x)
{
return x==fa[x]?x:fa[x]=find(fa[x]);
}
struct node
{
int u,v,w;
bool operator <(const node &a)const
{
return w<a.w;
}
}a[100005];
void dfs(int u,int lst)
{
dep[u]=dep[lst]+1;
for(auto it:e[u])
{
int v=it.first,w=it.second;
if(v==lst) continue;
st[v][0]=w;
up[v][0]=u;
dfs(v,u);
}
}
void init()
{
for(int j=1;j<=20;j++) for(int i=1;i<=n;i++) up[i][j]=up[up[i][j-1]][j-1];
for(int j=1;j<=20;j++) for(int i=1;i<=n;i++) st[i][j]=max(st[i][j-1],st[up[i][j-1]][j-1]);
}
int asklca(int u,int v)
{
if(dep[u]<dep[v]) swap(u,v);
for(int i=20;i>=0;i--) if(dep[up[u][i]]>=dep[v]) u=up[u][i];
if(u==v) return u;
for(int i=20;i>=0;i--) if(up[u][i]!=up[v][i])
{
u=up[u][i];
v=up[v][i];
}
return up[u][0];
}
int askmax(int u,int v)// u ---up---> v
{
int ret=0;
for(int i=20;i>=0;i--) if(dep[up[u][i]]>=dep[v])
{
ret=max(ret,st[u][i]);
u=up[u][i];
}
return ret;
}
int main()
{
cin>>n>>m;
for(int i=1;i<=m;i++) cin>>a[i].u>>a[i].v>>a[i].w;
sort(a+1,a+m+1);
for(int i=1;i<=n;i++) fa[i]=i;
ll ans1=0;
for(int i=1;i<=m;i++)
{
int u=a[i].u,v=a[i].v,w=a[i].w;
if(find(u)==find(v)) continue;
fa[find(u)]=find(v);
vis[i]=1;
ans1+=w;
e[u].push_back({v,w});
e[v].push_back({u,w});
}
cout<<ans1<<' ';
dfs(1,0);
init();
ll ans2=-1;
for(int i=1;i<=m;i++) if(!vis[i])
{
int u=a[i].u,v=a[i].v,w=a[i].w;
int lca=asklca(u,v);
int mx=max(askmax(u,lca),askmax(v,lca));
if(ans2==-1||ans2>ans1+w-mx) ans2=ans1+w-mx;
}
cout<<ans2;
return 0;
}