萌新求调,悬赏一关
查看原帖
萌新求调,悬赏一关
428889
Xile楼主2023/8/21 19:14

90分提交记录 改了半年了,舅舅萌新吧

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
#define N 300005
#define LL long long
using namespace std;
int n,m;
struct sd{
	int to,next,from,f;
	LL value;
}edge[N<<1],a[N<<1];
int head[N],tot;
inline void add(int x,int y,LL z){
	edge[++tot].to=y;
	edge[tot].from=x;
	edge[tot].value=z;
	edge[tot].next=head[x];
	head[x]=tot;
}
int fa[N];
inline int get(int x){
	return fa[x]==x?x:fa[x]=get(fa[x]);
}
inline bool change(int x,int y){
	int f1=get(x),f2=get(y);
	if(f1!=f2){
		fa[f1]=f2;
		return 1;
	}
	return 0;
}
bool cmp(sd x,sd y){
	return x.value<y.value;
}
int k;LL ans,ans1=1e9+2;
inline void kruskal(){
	for(int i=1;i<=n;i++) fa[i]=i;
	sort(a+1,a+1+m,cmp);
	for(int i=1;i<=m;i++){
		int x1=get(a[i].from),x2=get(a[i].to);
		if(change(x1,x2)){
			k++;
			ans+=a[i].value;
			a[i].f=1;
			add(a[i].from,a[i].to,a[i].value);
			add(a[i].to,a[i].from,a[i].value);
		}
		if(k==n-1) return;
	}
	return;
}
int d[N],f[N][25];
LL fmax[N][25],tmax[N][25];
queue<int > q;
inline void bfs(){
	q.push(1);
	d[1]=1;
	while(!q.empty()){
		int x=q.front();
		q.pop();
		for(int i=head[x];i;i=edge[i].next){
			int y=edge[i].to;
			if(d[y]) continue;
			q.push(y);
			d[y]=d[x]+1;
			f[y][0]=x;
			tmax[y][0]=-1;
			fmax[y][0]=edge[i].value;
			for(int i=1;i<=20;i++){
				f[y][i]=f[f[y][i-1]][i-1];
				fmax[y][i]=max(fmax[y][i-1],fmax[f[y][i-1]][i-1]);
				if(fmax[y][i-1]==fmax[f[y][i-1]][i-1]) tmax[y][i]=max(tmax[y][i-1],tmax[f[y][i-1]][i-1]);
				else {
					LL a=min(fmax[y][i-1],fmax[f[y][i-1]][i-1]);
					LL b=max(tmax[y][i-1],tmax[f[y][i-1]][i-1]);
					tmax[y][i]=max(a,b);
				}
			}
		}
	}
	return;
}
LL max1,max2;
inline void update(int x,int i){
	if(fmax[x][i]>max1) max2=max1,max1=fmax[x][i];
	else if(fmax[x][i]>max2&&fmax[x][i]!=max1) max2=fmax[x][i];
	if(tmax[x][i]>max1) max2=max1,max1=tmax[x][i];
	else if(tmax[x][i]>max2&&tmax[x][i]!=max1) max2=tmax[x][i];
	return;
}
inline void work(int x,int y,LL z){
	max1=0,max2=0;
	if(d[x]<d[y]) swap(x,y);
	for(int i=20;i>=0;i--){
		if(d[f[x][i]]>=d[y]){
			update(x,i);
			x=f[x][i];
		}
	}
	for(int i=20;i>=0;i--){
		if(f[x][i]!=f[y][i]){
			update(x,i);
			update(y,i);
			x=f[x][i],y=f[y][i];
		}
	}
	update(x,0);
	update(y,0); 
	if(max1==z) ans1=min(ans1,z-max2);
	else ans1=min(ans1,z-max1);
	return;
}
int main(){
	scanf("%d%d",&n,&m);
	for(int i=1;i<=m;i++)
		scanf("%d%d%lld",&a[i].from,&a[i].to,&a[i].value);
	kruskal();
	bfs();
	for(int i=1;i<=m;i++)
		if(!a[i].f)
			work(a[i].from,a[i].to,a[i].value);
	printf("%lld",ans+ans1);
	return 0;
}
2023/8/21 19:14
加载中...