kruskal+lca严格次小生成树 WA 40pts 求助
查看原帖
kruskal+lca严格次小生成树 WA 40pts 求助
526677
封禁用户楼主2022/11/15 14:04

检查不出来了……

#include<bits/stdc++.h>
using namespace std;
#define N 114514
#define M 1919810
#define ll long long
#define INF 114514191981000
ll n,m,x,y,z;
ll fa[N],tot,ans,total;
bool flag[3*N];
struct xx{
	ll next,from,to,val;
}aa[3*N],ed[2*N];
ll head[2*N],cnt;
ll lg[N],vis[N],f[N][21],dept[N];
ll max1[N][21],max2[N][21];
bool cmp(xx x,xx y){
	return x.val<y.val;
}
ll _max_(ll x,ll i,ll val){
	if(max1[x][i]!=val) return max1[x][i];
	else return max2[x][i];
} 
void add(ll x,ll y,ll z){
	ed[++cnt].next=head[x];
	ed[cnt].from=x;
	ed[cnt].to=y;
	ed[cnt].val=z;
	head[x]=cnt;
}
ll find(ll x){
	return x==fa[x]?x:find(fa[x]);
}
void kruskal(){
	sort(aa+1,aa+m+1,cmp);
	for(int i=1;i<=n;++i) fa[i]=i;
	for(int i=1;i<=m;++i){
		ll a=aa[i].from,b=aa[i].to,c=aa[i].val;
		if(find(a)==find(b)) return;
		tot++;
		fa[find(b)]=find(a);
		ans+=c;
		add(a,b,c),add(b,a,c);
		flag[i]=1;
		if(tot==n-1) break;
	}
}
void dfs(ll u,ll faa){
	for(int i=head[u];i;i=ed[i].next){
		ll v=ed[i].to,w=ed[i].val;
		if(v==faa) continue;
		dept[v]=dept[u]+1;
		f[v][0]=u;
		max1[v][0]=w;
		max2[v][0]=-INF;
		for(int j=1;j<=lg[dept[v]];++j){
			f[v][j]=f[f[v][j-1]][j-1];
			max1[v][j]=max(max1[f[v][j-1]][j-1],max1[v][j-1]);
			max2[v][j]=max(max2[f[v][j-1]][j-1],max2[v][j-1]);
			if(max1[v][i-1]!=max1[f[v][j-1]][j-1]) max2[v][j]=max(max2[v][j],min(max1[f[v][j-1]][j-1],max1[v][j-1]));
		}
		dfs(v,u);
	}
}
ll lca(ll a,ll b,ll c){
	ll ans=-INF;
	if(a==b) return a;
	if(dept[a]<dept[b]) swap(a,b);
	for(int i=lg[dept[a]];i>=0;--i)
		if(dept[f[a][i]]>=dept[b]){
			ans=max(ans,_max_(a,i,c));
			a=f[a][i];
		}
	if(a==b) return ans;
	for(int i=lg[dept[a]];i>=0;--i)
		if(f[a][i]!=f[b][i]){
			ans=max(ans,_max_(a,i,c));
			ans=max(ans,_max_(b,i,c));
			a=f[a][i],b=f[b][i];
		}
	ans=max(ans,_max_(a,0,c));
	ans=max(ans,_max_(b,0,c));
	return ans;
}
int main(){
	cin>>n>>m;
	for(int i=1;i<=m;++i) cin>>aa[i].from>>aa[i].to>>aa[i].val;
	kruskal();
	for(int i=1;i<=n;++i) lg[i]=lg[i>>1]+1;
	dept[1]=1;
	dfs(1,0);
	total=INF;
	for(int i=1;i<=m;++i){
		if(flag[i]||aa[i].from==aa[i].to) continue;
		ll u=aa[i].from,v=aa[i].to,w=aa[i].val;
		total=min(total,ans+w-lca(u,v,w));
	}
	cout<<total;
	return 0;
}
2022/11/15 14:04
加载中...