LCT不吸氧好像会T
查看原帖
LCT不吸氧好像会T
364033
cddˇ楼主2021/11/19 12:54

不开O2会T最后两个点

开了就过了

可能是哪写的有问题(?

#include<bits/stdc++.h>
#define LL long long
using namespace std;
const int maxn = 1e5+5;
const int maxm = 3e5+5;
struct sdd {
	int x,y,w,v;
}l[maxm];
int n,m;
LL ans=LLONG_MAX,MIN=0;
struct LCT {
	int ch[maxm<<1][2],fa[maxm<<1],rev[maxm<<1],ma[maxm<<1],val[maxm<<1],ma2[maxm<<1];
	int chk(int x) {return ch[fa[x]][1]==x;}
	int isroot(int x) {return ch[fa[x]][1]!=x&&ch[fa[x]][0]!=x;}
	void reserve(int x) {rev[x]^=1; swap(ch[x][1],ch[x][0]);}
	void pushup(int x) {
		ma[x]=val[x];
		int ls=ch[x][0],rs=ch[x][1];
		if (ls) {
			if (ma[ls]>ma[x]) ma2[x]=ma[x],ma[x]=ma[ls];
				else if (ma[ls]>ma2[x]) ma2[x]=ma[ls];
			if (ma2[ls]>ma2[x]) ma2[x]=ma2[ls];
		}
		if (rs) {
			if (ma[rs]>ma[x]) ma2[x]=ma[x],ma[x]=ma[rs];
				else if (ma[rs]>ma2[x]) ma2[x]=ma[rs];
			if (ma2[rs]>ma2[x]) ma2[x]=ma2[rs];
		}
	}
	void pushdown(int x) {
		if (rev[x]) {
			reserve(ch[x][1]);
			reserve(ch[x][0]);
			rev[x]=0;
		}
	}
	void rotate(int x) {
		int y=fa[x],z=fa[y],k=chk(x),w=ch[x][k^1];
		if (!isroot(y)) ch[z][chk(y)]=x;
		fa[x]=z;
		ch[y][k]=w; fa[w]=y;
		ch[x][k^1]=y; fa[y]=x;
		pushup(y); pushup(x);
	}
	void update(int x) {
		if (!isroot(x)) update(fa[x]);
		pushdown(x);
	}
	void splay(int x) {
		update(x);
		while (!isroot(x)) {
			int y=fa[x];
			if (!isroot(y))
				if (chk(x)==chk(y)) rotate(y);
					else rotate(x);
			rotate(x);
		}
		pushup(x);
	}
	void ccs(int x) {
		for (int y=0;x;x=fa[y=x])
			splay(x),ch[x][1]=y,pushup(x);
	}
	void makert(int x) {
		ccs(x); splay(x);
		reserve(x);
	}
	int findrt(int x) {
		ccs(x); splay(x); pushdown(x);
		while (ch[x][0]) x=ch[x][0],pushdown(x);
		splay(x);
		return x;
	}
	void link(int x,int y) {
		makert(x);
		fa[x]=y;
	}
	void split(int x,int y) {
		makert(x); ccs(y); splay(y);
	}
	void cut(int x,int y) {
		split(x,y);
		fa[x]=ch[y][0]=0;
	}
}st;
bool cmp(sdd x,sdd y) {return x.w<y.w;}
int main()
{
	scanf("%d%d",&n,&m);
	for (int i=1;i<=m;i++) {
		scanf("%d%d%d",&l[i].x,&l[i].y,&l[i].w);
		if (l[i].x>l[i].y) swap(l[i].x,l[i].y);
	}
	sort(l+1,l+1+m,cmp);
	int cnt=1,minl=1;
	for (int i=1;i<=m;i++) st.val[i+n]=l[i].w;
	for (int i=1;i<=m;i++) {
		int x=l[i].x,y=l[i].y;
		if (x==y) continue;
		if (st.findrt(x)==st.findrt(y)) continue;
		l[i].v=1; MIN+=l[i].w;
		st.link(x,i+n); st.link(i+n,y);
		st.val[i+n]=l[i].w;
	}
	for (int i=1;i<=m;i++) {  
		int x=l[i].x,y=l[i].y;
		if (l[i].v||x==y) continue;
		st.split(x,y);
		LL sum=MIN-st.ma[y]+l[i].w;
		if (sum>MIN) ans=min(ans,sum);
		sum=MIN-st.ma2[y]+l[i].w;
		if (sum>MIN) ans=min(ans,sum);
	}
 
	printf("%lld\n",ans);
	
	return 0;
}

2021/11/19 12:54
加载中...