模板。

非严格次小生成树

#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;
}
posted @ 2025-04-08 16:46  sapo1o  阅读(26)  评论(0)    收藏  举报