萌新求助,样例过不去却 AC 了
查看原帖
萌新求助,样例过不去却 AC 了
116015
bellmanford楼主2020/6/7 16:39

一件奇怪的事情,输出中间过程后发现是有一次查询是次大值没有赋上,可是我检查不出来错哪里了

#pragma GCC optimize("O3")
#include<algorithm>
#include<iostream>
#include<cstdio>
using namespace std;

#define int long long
const int M=4e5+5;

void swap(int &x,int &y){ return (void)(x^=y^=x^=y); }
int min(int x,int y){ return x<y?x:y; }
int max(int x,int y){ return x>y?x:y; }

int n,m,fa[M],val[M],hep[M],maxn[M],maxn2[M],lazy[M],ch[M][2];

int read(){
	int x=0,y=1;
	char ch=getchar();
	while(ch<'0'||ch>'9'){
		if(ch=='-') y=-1;
		ch=getchar();
	}
	while(ch>='0'&&ch<='9'){
		x=x*10+ch-'0';
		ch=getchar();
	}
	return x*y;
}

int get(int u){
	return (ch[fa[u]][0]==u||ch[fa[u]][1]==u);
}

void pushup(int u){
	int ls=ch[u][0],rs=ch[u][1];
	maxn[u]=max(val[u],max(maxn[ls],maxn[rs]));
	if(maxn[ls]>maxn[rs]) maxn2[u]=max(maxn2[ls],maxn[rs]);
	else if(maxn[rs]>maxn[ls]) maxn2[u]=max(maxn2[rs],maxn[ls]);
	else maxn2[u]=max(maxn2[ls],maxn2[rs]);
	if(val[u]>maxn[u]) maxn2[u]=maxn[u],maxn[u]=val[u];
	else if(val[u]<maxn[u]&&val[u]>maxn2[u]) maxn2[u]=val[u];
}

void flip(int u){
	swap(ch[u][0],ch[u][1]);
	lazy[u]^=1;
}

void pushdown(int u){
	if(!lazy[u]) return ;
	lazy[u]=0;
	if(ch[u][0]) flip(ch[u][0]);
	if(ch[u][1]) flip(ch[u][1]);
}

void rotate(int u){
	int a=fa[u],b=fa[a],d1=(ch[a][1]==u),d2=(ch[b][1]==a);
	int v=ch[u][d1^1];
	if(get(a)) ch[b][d2]=u;
	ch[u][d1^1]=a,ch[a][d1]=v;
	if(v) fa[v]=a;
	fa[a]=u,fa[u]=b;
	pushup(a),pushup(u);
}

void Splay(int u){
	int v=u,top=0;
	hep[++top]=v;
	while(get(v)) hep[++top]=v=fa[v];
	while(top) pushdown(hep[top--]);
	while(get(u)){
		v=fa[u],top=fa[v];
		if(get(v)) rotate((ch[v][0]==u)^(ch[top][0]==v)?u:v);
		rotate(u);
	}
	pushup(u);
}

void Access(int u){
	for(int v=0;u;u=fa[v=u]){
		Splay(u);
		ch[u][1]=v;
		pushup(u);
	}
}

void makeroot(int u){
	Access(u);
	Splay(u);
	flip(u);
}

void Split(int u,int v){
	makeroot(u);
	Access(v);
	Splay(v);
}

int findroot(int u){
	Access(u);
	Splay(u);
	while(ch[u][0]){
		pushdown(u);
		u=ch[u][0];
	}
	return u;
}

void Link(int u,int v){
	makeroot(u);
	if(findroot(v)!=u) fa[u]=v;
}

void Cut(int u,int v){
	Split(u,v);
	if(findroot(v)==u&&fa[u]==v&&!ch[u][1]){
		fa[u]=ch[v][0]=0;
		pushup(v);
	}
}

struct CuCun{
	int x,y,z;
}c[M];
bool cmp(CuCun x,CuCun y){
	return x.z<y.z;
}

int fath[M];
int find(int x){
	if(fath[x]!=x) fath[x]=find(fath[x]);
	return fath[x];
}

void solve(){
	n=read(),m=read();int Ans=0,Anss=1e18,num=n;
	for(int i=1;i<=n;i++) fath[i]=i,val[i]=maxn[i]=0;
	for(int i=1;i<=m;i++) c[i].x=read(),c[i].y=read(),c[i].z=read();
	sort(c+1,c+m+1,cmp);
	for(int i=1;i<=m;i++){
		int x=c[i].x,y=c[i].y,z=c[i].z;
		int fx=find(x),fy=find(y);
		if(fx==fy){
			Split(x,y);
			Anss=min(Anss,z-(z>maxn[y]?maxn[y]:maxn2[y]));
//			printf("%lld %lld %lld %lld %lld\n",x,y,z,maxn[y],maxn2[y]);
		}
		else{
			makeroot(x);
			fa[fa[x]=++num]=y;
			Ans+=(maxn[num]=val[num]=z);
			fath[fx]=fy;
		}
	}
	printf("%lld\n",Ans+Anss);
}

signed main(){
	solve();
}
2020/6/7 16:39
加载中...