P4180次小生成树求调(WA*4)
  • 板块学术版
  • 楼主A2ure_Sky
  • 当前回复0
  • 已保存回复0
  • 发布时间2024/8/14 12:21
  • 上次更新2024/8/14 14:41:09
查看原帖
P4180次小生成树求调(WA*4)
665592
A2ure_Sky楼主2024/8/14 12:21
#include<bits/stdc++.h>
#define INF 1e16
#define ll long long 
using namespace std;
const int N=1e5+10;
const int M=6e5+10;
int n,m;
ll sum,ans,val1,val2,f[N][32],g[N][32][2],dep[N],fa[M];

int head[N],idx;
struct node{
	int nxt,v,w;
}e[M];
void add(int u,int v,int w){
	e[++idx].nxt=head[u];
	e[idx].v=v;
	e[idx].w=w;
	head[u]=idx;
}

struct line{
	int x,y,z;
	bool vis;
}s[M];
bool cmp(line l1,line l2){
	return l1.z<l2.z;
}
int find(int x){
	if(fa[x]==x) return x;
	else return fa[x]=find(fa[x]);	
}
struct LCA{
	void bfs(){
		dep[1]=0;
		queue<int> q;
		q.push(1);
		while(!q.empty()){
			int x=q.front();
			q.pop();
			for(int i=head[x];i;i=e[i].nxt){
				int y=e[i].v;
				if(y==f[x][0]) 
					continue;
				dep[y]=dep[x]+1;
				f[y][0]=x;
				g[y][0][0]=e[i].w;
				g[y][0][1]=-INF;
				q.push(y);
				for(int j=1;j<=30;j++){
					f[y][j]=f[f[y][j-1]][j-1];
					if(g[y][j-1][0]!=g[f[y][j-1]][j-1][0]){
						g[y][j][0]=max(g[y][j-1][0],g[f[y][j-1]][j-1][0]);
						g[y][j][1]=min(g[y][j-1][0],g[f[y][j-1]][j-1][0]);
					}
					else{
						g[y][j][0]=g[y][j-1][0];
						g[y][j][1]=max(g[y][j-1][1],g[f[y][j-1]][j-1][1]);
					}
				}
			}
		}
	}
	inline void update2(int x){
		if(x>val1){
			val2=val1;
			val1=x;
		}
		else if(x>val2&&x!=val1) val2=x;
	}
	void update1(int x,int y){
		update2(g[x][y][0]);
		update2(g[x][y][1]);
	}
	void Find(int x,int y){
		val1=val2=-INF;
		if(dep[x]<dep[y]) swap(x,y);
		for(int i=30;i>=0;i--)
			if(dep[f[x][i]]>=dep[y]){
				x=f[x][i];
				update1(x,i);
			}
		if(x==y) 
			return;
		for(int i=30;i>=0;i--)
			if(f[x][i]!=f[y][i]){
				update1(x,i);
				update1(y,i);
				x=f[x][i];
				y=f[y][i];
			}
		update1(x,0);
		update1(y,0);
	}
}lca;
void kruskal(){
	sort(s+1,s+m+1,cmp);
	for(int i=1;i<=m;i++){
		int a=find(s[i].x),b=find(s[i].y);
		if(a==b)
			continue;
		s[i].vis=true;
		fa[a]=b;
		sum+=s[i].z;
		add(s[i].x,s[i].y,s[i].z);
		add(s[i].y,s[i].x,s[i].z);
	}
}
int main(){
	ios::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);
	cin>>n>>m;
	for(int i=1;i<=m;i++){
		int x,y,z;
		cin>>x>>y>>z;
		s[i].x=x;
		s[i].y=y;
		s[i].z=z;
		fa[i]=i;
	}
	kruskal();
	lca.bfs();
	ans=INF;
	for(int i=1;i<=m;i++)
		if(!s[i].vis){
			lca.Find(s[i].x,s[i].y);
			if(val1!=s[i].z) ans=min(ans,sum-val1+s[i].z);
			else ans=min(ans,sum-val2+s[i].z);
		}
	cout<<ans;
	return 0;
}
2024/8/14 12:21
加载中...