本人刚学严格次小生成树,90pts求助
查看原帖
本人刚学严格次小生成树,90pts求助
230580
Suzt_ilymtics楼主2020/10/10 10:03

最后一个点WA掉了

#include<iostream>
#include<cstdio>
#include<algorithm>
#define LL long long
#define INF 2146473647000000
const int MAXN = 1e5+5;
const int MAXM = 3e5+5;
using namespace std;
struct edge{
	LL from,to,nxt;
	LL w;
	bool operator < (const edge &b) const {return w < b.w;}
}e[MAXM << 1],a[MAXM];
LL head[MAXN],num_edge;
LL n,m,cnt;
LL fa[MAXN];
LL f[MAXN][21];
LL maxm[MAXN][21];
LL minn[MAXN][21];
LL depth[MAXN];
bool vise[MAXM];


inline void add(LL from,LL to,LL w){
	e[++num_edge].nxt = head[from]; 	e[num_edge].to = to;
	e[num_edge].from = from;			e[num_edge].w = w;
	head[from] = num_edge;
}

inline LL find(LL x){return fa[x] == x ? x : fa[x] = find(fa[x]);}

inline void init_lca(){
	for(LL i = 1; i <= 20; ++i){
		for(LL j = 1; j <= n; ++j){
			f[j][i] = f[f[j][i-1]][i-1];
			maxm[j][i] = max(maxm[j][i-1],maxm[f[j][i-1]][i-1]);
			minn[j][i] = max(minn[j][i-1],minn[f[j][i-1]][i-1]);
			//更新次大值 
			if(maxm[j][i-1] > maxm[f[j][i-1]][i-1]){
				minn[j][i] = max (minn[j][i], maxm[f[j][i-1]][i-1]);
			}//没有判断 = ,是因为保证存的次大值不等于最大值 
			else if(maxm[j][i-1] < maxm[f[j][i-1]][i-1]){
				minn[j][i] = max (minn[j][i], maxm[j][i-1]);
			}
		}
	}
}

inline LL get_lca(LL u,LL v){
	if(depth[u] > depth[v]){
		swap(u,v);
	}
	for(LL i=20;i>=0;--i){
		if(depth[f[v][i]] < depth[u]) continue;
		else v = f[v][i];
	}
	if(u == v)	return u;
	for(LL i=20;i>=0;--i){
		if(f[v][i] != f[u][i]){
			v = f[v][i];
			u = f[u][i];
		}
	}
	return f[u][0];
}

inline void dfs(LL u,LL fa){
	f[u][0] = fa;
	for(LL i = head[u]; i; i = e[i].nxt){
		LL v = e[i].to;
		if(v == fa) continue;
		else{
			depth[v] = depth[u] + 1;
			maxm[v][0] = e[i].w;
			minn[v][0] = -INF;
			dfs(v,u);
		}
	}
}

inline void kls(){
	for(LL i=1;i<=m;++i){
		LL uf = find(a[i].from), vf = find(a[i].to);
		if(uf == vf) continue;
		else{
			fa[uf] = vf;
			cnt += a[i].w;
			add(a[i].from,a[i].to,a[i].w);
			add(a[i].to,a[i].from,a[i].w);
			vise[i] = 1;
 		}
	}
}

inline LL qmax(LL u, LL v, LL maxx){
	LL Ans = -INF;
	for(LL i = 20; i >= 0; --i){
		if(depth[f[u][i]] >= depth[v]){
			if(maxx != maxm[u][i]){
				Ans = max (Ans, maxm[u][i]);
			}
			else{
				Ans = max (Ans, minn[u][i]);
			}
			u = f[u][i];
		}
	}
	return Ans;
}

int main()
{
	scanf("%lld%lld",&n,&m);
	for(LL i=1,u,v,w;i<=m;++i){
		scanf("%lld%lld%lld",&a[i].from,&a[i].to,&a[i].w);
	}
	for(LL i=1;i<=n;++i) {fa[i] = i;}
	
	sort(a+1,a+m+1);
	kls();
	
	minn[1][0] = -INF; 
	depth[1] = 1;
	
	dfs(1,-1);
	init_lca();
	
	LL ans = INF;
	
	for(LL i = 1; i<=m; ++i){
		if(!vise[i]){
			LL u = a[i].from, v = a[i].to, w = a[i].w;
			LL lca = get_lca(u,v);
			LL maxu = qmax(u, lca, w);
			LL maxv = qmax(v, lca, w);
			ans = min(ans, cnt - max(maxu,maxv) + w);
		}
	}
	
	printf("%lld",ans);
	
	return 0;
}
2020/10/10 10:03
加载中...