测试点本地能过,测评全TLE
查看原帖
测试点本地能过,测评全TLE
728401
Peaky楼主2024/11/20 17:49

实现:kruskal+LCA

#include<bits/stdc++.h>
#define int long long
#define x first
#define y second
using namespace std;
const int N=6e5+10,inf=1e18,mod=1e9+7;
typedef unsigned long long ull;
typedef pair<int,int> pii;
typedef long long ll;
/*

*/
struct Edge{
	int u,v,w;
	bool operator < (const Edge&x)const {return w<x.w;}
}edg[N];
int head[N],edge[N],W[N],last[N],idx;
void add(int u,int v,int w){
	W[++idx]=w;
	edge[idx]=v;
	last[idx]=head[u];
	head[u]=idx;
}
int n,m,f[N],ans=inf,tr,vis[N];
int find(int x) {return x==f[x]?x:f[x]=find(f[x]);}
void kruskal(){
	sort(edg+1,edg+m+1);
	for(int i=1;i<=m;i++){
		int u=edg[i].u,v=edg[i].v;
		if(find(u)==find(v)) continue;
		f[find(u)]=find(v);
		int w=edg[i].w;
		add(u,v,w);
		add(v,u,w);
		vis[i]=1;
		tr+=w;
	} 
}
int mt[N][32],ct[N][32];
int deep[N],father[N][32];
int dfs(int x,int fa,int w){
	deep[x]=deep[fa]+1;
	father[x][0]=fa;
	mt[x][0]=w;
	for(int i=1;i<=20;i++){
		int lfa=father[x][i-1];
		father[x][i]=father[lfa][i-1];
		mt[x][i]=max(mt[x][i],mt[lfa][i-1]);
		ct[x][i]=max(ct[x][i],ct[lfa][i-1]);
		if(mt[x][i]!=mt[lfa][i-1]&&mt[lfa][i-1]>ct[x][i])
			ct[x][i]=mt[lfa][i-1];
	}
	for(int i=head[x];i;i=last[i])
		if(edge[i]!=fa) dfs(edge[i],x,W[i]);
}
int LCA(int x,int y){
	if(deep[x]<deep[y]) swap(x,y);
	for(int i=20;i>=0;i--) if(deep[x]-(1<<i)>=deep[y]) x=father[x][i];
	if(x==y) return x;
	for(int i=20;i>=0;i--){
		if(father[x][i]!=father[y][i]) x=father[x][i],y=father[y][i];
	}
	return father[x][0];
}
int get(int u,int v,int k){
	int res=-inf;
	for(int i=20;i>=0;i--){
		if(deep[father[u][i]]<deep[v]) continue;
		if(mt[u][i]!=k) res=max(mt[u][i],res);
		else res=max(res,ct[u][i]);
		u=father[u][i];
	}
	return res;
}
signed main(){
	cin>>n>>m;
	for(int i=1;i<=n;i++) f[i]=i;
	for(int i=1;i<=m;i++){
		int u,v,w;
		cin>>u>>v>>w;
		edg[i]={u,v,w};
	}
	kruskal();
	dfs(1,0,0);
	for(int i=1;i<=m;i++){
		if(vis[i]) continue;
		int u=edg[i].u,v=edg[i].v;
		int w=edg[i].w;
		int fa=LCA(u,v);
		int mu=get(u,fa,w);
		int mv=get(v,fa,w);
		ans=min(ans,tr-max(mu,mv)+w);
	}
	cout<<ans;
	return 0;
}

in:

4 6
1 2 1
1 3 3
1 4 10
1 2 5
2 2 2
1 1 4

ans:

18
2024/11/20 17:49
加载中...