次小生成树
查看原帖
次小生成树
115067
Adis_FireDevil楼主2021/10/15 21:34

次小生成树,第4个点WA,第10个点TLE

#include<bits/stdc++.h>
using namespace std;
int n,m,k=1,rt,lc,l;
int q[100011],fa[100011];
int f[100011][22],lg[100011],d[100011];
long long ans,minn1,minn2,t,t2,maxn[100011][22],maxn2[100011][22];
bool b,c[300011];
struct edge {
	long long to,ne,num;
} e[300011];
struct ed {
	long long u,v,num;
} a[300011];
inline int read() {
	int d=0;
	char s=getchar();
	while(s>'9'||s<'0') {
		s=getchar();
	}
	while(s<='9'&&s>='0') {
		d=(d<<3)+(d<<1)+s-'0';
		s=getchar();
	}
	return d;
}
int find(int a) {
	if(fa[a]==a)return a;
	else return(find(fa[a]));
}
long long cmp(ed a,ed b) {
	return a.num<b.num;
}
void kruskal(int i) {
	b=0;
	while(!b) {
		int u1=find(a[k].u),v1=find(a[k].v);
		fa[a[k].u]=u1;
		fa[a[k].v]=v1;
		if(u1!=v1) {
			c[k]=1;
			l++;
			e[l].ne=q[a[k].u];
			q[a[k].u]=l;
			e[l].to=v1;
			e[l].num=a[k].num;
			fa[v1]=u1;
			ans+=a[k].num;
			b=1;
		}
		k++;
	}
}
void dfs(int a,int b,int c) {
	if(b!=0)d[a]=d[b]+1;
	f[a][1]=b;
	maxn[a][1]=c;
	for(int i=2; i<=lg[d[a]]; i++) {
		f[a][i]=f[f[a][i-1]][i-1];
		maxn[a][i]=max(maxn[a][i-1],maxn[f[a][i-1]][i-1]);
	}
	if(d[a]>=2){
		if(maxn[a][1]!=maxn[f[a][1]][1])maxn2[a][2]=min(maxn[a][1],maxn[f[a][1]][1]);
		else maxn2[a][2]=0;
		for(int i=3; i<=lg[d[a]]; i++) {
			maxn2[a][i]=max(maxn2[a][i-1],maxn2[f[a][i-1]][i-1]);
			if(maxn[a][i-1]!=maxn[f[a][i-1]][i-1]){
				maxn2[a][i]=max(maxn2[a][i],min(maxn[a][i-1],maxn[f[a][i-1]][i-1]));
			}
		}
	}
	for(int i=q[a];; i=e[i].ne) {
		if(i==0)break;
		dfs(e[i].to,a,e[i].num);
	}
}
void lca(int u,int v){
	if(d[u]>d[v])swap(u,v);
	while(d[u]!=d[v]){
		if(t==0)t2=maxn2[v][max(1,lg[d[v]-d[u]])];
		else{
			if(t!=maxn[v][max(1,lg[d[v]-d[u]])])t2=max(min(t,maxn[v][max(1,lg[d[v]-d[u]])]),max(t2,maxn2[v][max(1,lg[d[v]-d[u]])]));
		}
		t=max(t,maxn[v][max(1,lg[d[v]-d[u]])]);
		v=f[v][max(1,lg[d[v]-d[u]])];
	}
	if(u==v){
		return;
	}
	int q=lg[d[u]]+1;
	while(q!=0){
		q--;
		if(f[u][q]==f[v][q]){
			lc=f[u][q];
			continue;
		}
		else{
			t=max(t,max(maxn[u][q],maxn[v][q]));
			if(t!=max(maxn[u][q],maxn[v][q]))t2=max(min(t,max(maxn[u][q],maxn[v][q])),t2);
			t2=max(max(maxn2[u][q],maxn2[v][q]),t2);
			if(maxn[u][q]!=maxn[v][q])
			u=f[u][q];
			v=f[v][q];
		}
	}
	while(d[u]!=d[lc]){
		t2=max(t2,max(maxn2[u][max(1,lg[d[v]-d[u]])],maxn2[v][max(1,lg[d[v]-d[u]])]));
		if(maxn[u][max(1,lg[d[v]-d[u]])]!=maxn[v][max(1,lg[d[v]-d[u]])]){
			t2=max(t2,min(maxn[u][max(1,lg[d[v]-d[u]])],maxn[v][max(1,lg[d[v]-d[u]])]));
		}
		t=max(maxn[u][max(1,lg[d[v]-d[u]])],maxn[v][max(1,lg[d[v]-d[u]])]);
		u=f[u][max(1,lg[d[v]-d[u]])];
		v=f[v][max(1,lg[d[v]-d[u]])];
	}
}
int main() {
	n=read();
	m=read();
	for(int i=1; i<=m; i++) {
		a[i].u=read();
		a[i].v=read();
		a[i].num=read();
	}
	int j=1,w=0;
	for(int i=1; i<=n; i++) {
		if(j==i)j<<=1,w++,lg[i]=w;
		else lg[i]=w;
	}
	for(int i=1; i<=n; i++)fa[i]=i;
	sort(a+1,a+m+1,cmp);
	for(int i=1; i<n; i++)kruskal(i);
	rt=find(1);
	dfs(rt,0,0);
	minn1=1000000007;
	for(int i=1; i<=m; i++) {
		if(c[i])continue;
		lc=0;
		t=0;
		t2=0;
		lca(a[i].u,a[i].v);
		if(t==a[i].num)minn1=min(minn1,a[i].num-t2);
		else if(minn1>a[i].num-t)minn1=a[i].num-t;
	}
	cout<<ans+minn1;
}
2021/10/15 21:34
加载中...