还是我
查看原帖
还是我
1353330
K_J_M楼主2024/8/1 12:04
#include<bits/stdc++.h>
using namespace std;
#define int long long
const int N = 1e5+10;
const int M = 3e5+10;
int n,m;
int f[N],fa[N][20],g[N][20],h[N][20],dep[N],lg[N],s[M];
struct Edge{
	int x,y,z;
}edge[M];
struct node{
	int id,w;
};
vector<node>e[N];
bool cmp(Edge a,Edge b){
	return a.z<b.z;
}
void dfs(int x,int fath,int y){
	fa[x][0]=fath,dep[x]=dep[fath]+1,g[x][0]=y,h[x][0]=-1;
	for(int i=1;i<=lg[dep[x]];i++) fa[x][i]=fa[fa[x][i-1]][i-1];
	for(int i=1;i<=lg[dep[x]-1];i++){
		if(g[x][i-1]>g[fa[x][i-1]][i-1]){
			g[x][i]=g[x][i-1];
			h[x][i]=max(g[fa[x][i-1]][i-1],h[x][i-1]);
		}else{
			if(g[fa[x][i-1]][i-1]>g[x][i-1]){
				g[x][i]=g[fa[x][i-1]][i-1];
				h[x][i]=max(g[x][i-1],h[fa[x][i-1]][i-1]);
			}else{
				g[x][i]=g[x][i-1];
				h[x][i]=max(h[x][i-1],h[fa[x][i-1]][i-1]);
			}
		}
	}
	for(int i=0;i<e[x].size();i++){
		int to=e[x][i].id;
		if(to==fath) continue;
		dfs(to,x,e[x][i].w); 
	}
}
int LCA(int a,int b){
	if(dep[a]<dep[b]) swap(a,b);
	while(dep[a]>dep[b]) a=fa[a][lg[dep[a]-dep[b]]];
	if(a==b) return a;
	for(int k=lg[dep[a]];k>=0;k--){
		if(fa[a][k]!=fa[b][k]){
			a=fa[a][k],b=fa[b][k];
		}
	}
	return fa[a][0];
}
int Getmax(int x,int fx){
	int ans=0;
	while(dep[x]>dep[fx]){
		ans=max(ans,g[x][lg[dep[x]-dep[fx]]]);
		x=fa[x][lg[dep[x]-dep[fx]]];
	}
	return ans;
}
int Getcmax(int x,int fx){
	int ans=-1,mans=0;
	while(dep[x]>dep[fx]){
		if(mans<g[x][lg[dep[x]-dep[fx]]]){
			ans=mans; 
			mans=g[x][lg[dep[x]-dep[fx]]];
		}else{
			if(mans>g[x][lg[dep[x]-dep[fx]]]){
				ans=max(ans,g[x][lg[dep[x]-dep[fx]]]);
			}else{
				ans=max(ans,h[x][lg[dep[x]-dep[fx]]]);
			}
		}
		x=fa[x][lg[dep[x]-dep[fx]]];
	}
	return ans;
}
int find(int x){
	return f[x]==x? x:f[x]=find(f[x]);
}
signed main(){
	scanf("%lld%lld",&n,&m);
	for(int i=1;i<=n;i++) f[i]=i;
	for(int i=1;i<=m;i++){
		scanf("%lld%lld%lld",&edge[i].x,&edge[i].y,&edge[i].z);
	}
	sort(edge+1,edge+m+1,cmp);
	int tot=0,ans=0x3fffffffffffffff,sum=0;
	for(int i=1;i<=m;i++){
		if(edge[i].x==edge[i].y) continue;
		int fx=find(edge[i].x),fy=find(edge[i].y);
		if(fx==fy){
			s[++tot]=i;
			continue;
		}
		f[fx]=fy;
		e[edge[i].x].push_back({edge[i].y,edge[i].z});
		e[edge[i].y].push_back({edge[i].x,edge[i].z});//建新树 
		sum+=edge[i].z;
	}
	for(int i=1;i<=n;i++) lg[i]=lg[i-1]+(1<<(lg[i-1]+1)==i);
	dfs(1,0,0);
	for(int i=1;i<=tot;i++){
		int u=edge[s[i]].x,v=edge[s[i]].y,w=edge[s[i]].z;
		int lca=LCA(u,v);
		int F=Getmax(u,lca),Q=Getmax(v,lca);
		int maxn=max(F,Q);//环上的最大值 
		int cmaxn=-1;
		if(F!=Q){
			cmaxn=min(F,Q);
		}else{
			cmaxn=max(Getcmax(u,lca),Getcmax(v,lca));
		}
		if(maxn!=w){//替换 
			ans=min(ans,sum-maxn+w);
		}else{
			if(cmaxn!=-1) ans=min(ans,sum-cmaxn+w);
		}
	}
	printf("%lld",ans);
	return 0;
}

改了一些最大值和次大值的判断,但是还是wa a同样的地方,求条

2024/8/1 12:04
加载中...