萌新求助,80分求助
查看原帖
萌新求助,80分求助
135258
charm1楼主2021/2/21 23:03

RT

#include <bits/stdc++.h>
#define pii pair <int,int>
#define int long long
using namespace std;
const int maxn=100005;
const int maxm=300005;
const int logn=25;
const int INF=(int)(1e18)+5;
int n,m,cnt,l,r,ans;
int dp[maxn][logn][2],fa[maxn][logn];
int dep[maxn],fa_[maxn],head[maxn],q[maxn];
bool vis[maxm];
struct edge{
	int v,nxt,val;
}a[maxm<<1];
struct sav{
	int x,y,val;
}b[maxm];
bool cmp(sav x,sav y){
	return x.val<y.val;
}
int get(int x){
	return x==fa_[x]?x:fa_[x]=get(fa_[x]);
}
void add(int x,int y,int val){
	++cnt;
	a[cnt].v  =y;
	a[cnt].val=val;
	a[cnt].nxt=head[x];
	head[x]=cnt;
}
pii maxx(int x1,int y1,int x2,int y2){
	int x,y;
	if(x1==x2){
		x=x1;
		y=max(y1,y2);
	}
	if(x1>x2){
		x=x1;
		y=max(x2,y1);
	}
	if(x1<x2){
		x=x2;
		y=max(x1,y2);
	}
	return make_pair(x,y);
}
inline int read(){
	int ret=0,f=1;	char ch=getchar();
	while(!isdigit(ch)){if(ch=='-')f=-f;ch=getchar();}
	while(isdigit(ch)){ret=ret*10+ch-'0';ch=getchar();}
	return ret*f;
}
void scan(){
	int k;
	memset(dp,-1,sizeof(dp));
	n=read();   m=read();
	for(k=1;k<=m;k++){
		int x,y,val;
		x=read();   y=read();   val=read();
		b[k].x=x;   b[k].y=y;   b[k].val=val;
	}
	sort(b+1,b+m+1,cmp);
}
void prim(){
	int k;
	for(k=1;k<=n;k++)   fa_[k]=k;
	for(k=1;k<=m;k++){
		int x=b[k].x,y=b[k].y,val=b[k].val;
		int fx=get(x),fy=get(y);
		if(fx==fy)  continue;
		fa_[fx]=fy; ans+=val;   vis[k]=1;
		add(x,y,val);   add(y,x,val);
	}
//	printf("最小生成树边权和为%d\n",ans);
}
void dfs(int x,int f){
	int k;
	fa[x][0]=f; dep[x]=dep[f]+1;
	for(k=head[x];k;k=a[k].nxt){
		int v=a[k].v,val=a[k].val;
		if(v==f)    continue;
		dfs(v,x);
		dp[v][0][0]=val;
	}
}
void bfs(){
	int k;
	q[l=r=1]=1;
	while(l<=r){
		int x=q[l++];
		for(k=head[x];k;k=a[k].nxt){
			int v=a[k].v,val=a[k].val;
			if(dep[v]<dep[x]) continue;
			q[++r]=v;
		}
		for(k=1;k<logn;k++){
			int f=fa[x][k-1];
			pii t=maxx(dp[x][k-1][0],dp[x][k-1][1],dp[f][k-1][0],dp[f][k-1][1]);
			dp[x][k][0]=t.first;
			dp[x][k][1]=t.second;
			fa[x][k]=fa[f][k-1];
		}
	}
}
pii LCA(int x,int y){
	int k;  int ans1,ans2;
	ans1=ans2=-1;
	if(dep[y]>dep[x])   swap(x,y);
	for(k=logn-1;k>=0;k--){
		int f=fa[x][k],a1=dp[x][k][0],b1=dp[x][k][1];
		if(dep[f]<=dep[y]){
			pii t=maxx(ans1,ans2,a1,b1);
			x=f;
			ans1=t.first;
			ans2=t.second;
		}
	}
	if(x==y)    return make_pair(ans1,ans2);
	for(k=logn-1;k>=0;k--){
		int fx=fa[x][k],fy=fa[y][k];
		if(fx!=fy) {
			pii t=maxx(dp[x][k][0],dp[x][k][1],dp[y][k][0],dp[y][k][1]);
			int a1=t.first,b1=t.second;
			t=maxx(a1,b1,ans1,ans2);
			x=fx;	y=fy;
			ans1=t.first;
			ans2=t.second;
		}
	}
	return make_pair(ans1,ans2);
}
int calc(){
	int k,j,i;
	int ans=INF;
	for(k=1;k<=m;k++){
		if(vis[k])  continue;
		int x=b[k].x,y=b[k].y,val=b[k].val;
		pii t=LCA(x,y); int x1=t.first,y1=t.second;
		int ans1;
		if(val!=x1)	ans1=val-x1;
		else        ans1=val-y1;
		ans=min(ans,ans1);
	}
	return ans;
}
void solve(){
	ans+=calc();
	printf("%lld\n",ans);
}
void prework(){
	dep[1]=1;	dfs(1,0);
	int k,j,i;
	bfs();
}
signed main(){
	int k,j,i;
//	freopen("ex_tree1 (1).in","r",stdin);
	scan();	prim();	prework();  solve();
	return 0;
}
2021/2/21 23:03
加载中...