严格次小生成树0pts求调
查看原帖
严格次小生成树0pts求调
713562
hahaxiang楼主2023/3/24 19:37
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=1e5+100;
const int M=3e5+100;
struct road{
	int to,val;
};
struct edge{
	int u,v,w;
};
int n,m;
int fa[N],num;
edge a[M];
int d[N],s[N],z[N],FA[N];
int tp[N],L[N],R[N],deep;
vector<road>p[N];
int st1[N][21],st2[N][21]; 
int oans,ans=LLONG_MAX;
int get1(int l,int r)
{
	int k=log2(r-l+1);
	return max(st1[l][k],st1[r-(1<<k)+1][k]);
}
int get2(int l,int r)
{
	int k=log2(r-l+1);
	vector<int>pl;
	pl.push_back(st1[l][k]);
	pl.push_back(st1[r-(1<<k)+1][k]);
	pl.push_back(st2[l][k]);
	pl.push_back(st2[r-(1<<k)+1][k]);
	pl.push_back(0);
	sort(pl.begin(),pl.end());
	k=unique(pl.begin(),pl.end())-pl.begin();
	return pl[k-2];
}
int find(int x)
{
	if(fa[x]!=x)
	fa[x]=find(fa[x]);
	return fa[x];
}
void query(int x,int y)
{
	fa[find(x)]=find(y);
	return;
}
void dfs1(int x,int fa)
{
	d[x]=d[fa]+1;
	FA[x]=fa;
	s[x]=1;
	int maxs=0;
	for(int i=0;i<p[x].size();i++)
	{
		road xx=p[x][i];
		if(xx.to==fa)
		continue;
		dfs1(xx.to,x);
		s[x]+=s[xx.to];
		if(s[xx.to]>maxs)
		{
			maxs=s[xx.to];
			z[x]=xx.to;
		}
	}
	return;
}
void dfs2(int x,int fa,int old)
{
	L[x]=++deep;
	tp[x]=old;
	if(z[x]!=0)
	{
		dfs2(z[x],x,old);
	}
	for(int i=0;i<p[x].size();i++)
	{
		road xx=p[x][i];
		if(xx.to==fa)
		continue;
		else if(xx.to==z[x])
		{
			st1[L[xx.to]][0]=xx.val;
			continue;
		}
		dfs2(xx.to,x,xx.to);
		st1[L[xx.to]][0]=xx.val;
	}
	R[x]=deep;
	return;
}
void solve(int id)
{
	int x=a[id].u;
	int y=a[id].v;
	vector<int>pl;
	pl.push_back(0);
	while(tp[x]!=tp[y])
	{
		if(d[tp[x]]<d[tp[y]])
		swap(x,y);
		pl.push_back(get1(L[tp[x]],L[x]));
		pl.push_back(get2(L[tp[x]],L[x]));
		x=FA[tp[x]];
	}
	if(d[x]<d[y])
	swap(x,y);
	if(x!=y)
	{
		pl.push_back(get1(L[y]+1,L[x]));
		pl.push_back(get2(L[y]+1,L[x]));
	}
	sort(pl.begin(),pl.end());
	int k=unique(pl.begin(),pl.end())-pl.begin();
	if(pl[k-1]==a[id].w)
	{
		if(pl[k-2]==0)
		return;
		else
		ans=min(ans,oans-pl[k-2]+a[id].w);
	}
	else
	{
		ans=min(ans,oans-pl[k-1]+a[id].w);
	}
	return;
}
signed main()
{
	ios::sync_with_stdio(0);
	cin.tie(0),cout.tie(0);
	cin>>n>>m;
	for(int i=1;i<=n;i++)
	{
		fa[i]=i;
	}
	for(int i=1;i<=m;i++)
	{
		cin>>a[i].u>>a[i].v>>a[i].w;
		if(a[i].u==a[i].v)
		{
			i--;
			m--;
		} 
	}
	for(int i=1;i<=m;i++)
	{
		if(find(a[i].u)!=find(a[i].v))
		{
			query(a[i].u,a[i].v);
			p[a[i].u].push_back(road{a[i].v,a[i].w});
			p[a[i].v].push_back(road{a[i].u,a[i].w});
			num++;
			oans+=a[i].w;
		}
		if(num==n-1)
		break;
	}
	dfs1(1,0);
	dfs2(1,0,1);
	for(int i=1;(1<<i)<=n;i++)
	{
		for(int j=1;j+(1<<i)-1<=n;j++)
		{
			st1[j][i]=max(st1[j][i-1],st1[j+(1<<i-1)][i-1]);
			vector<int>pl;
			pl.push_back(st2[j][i-1]);
			pl.push_back(st2[j+(1<<i-1)][i-1]);
			pl.push_back(st1[j][i-1]);
			pl.push_back(st1[j+(1<<i-1)][i-1]);
			pl.push_back(0);
			sort(pl.begin(),pl.end());
			int k=unique(pl.begin(),pl.end())-pl.begin();
			st2[j][i]=pl[k-2];
		}
	}
	for(int i=1;i<=m;i++)
	solve(i);
	cout<<ans;
	return 0;
}

2023/3/24 19:37
加载中...