社区讨论

帮帮我吧,我RE了

P4172[WC2006] 水管局长参与者 3已保存回复 8

讨论操作

快速查看讨论及其快照的属性,并进行相关操作。

当前回复
8 条
当前快照
1 份
快照标识符
@mi86m7q3
此快照首次捕获于
2025/11/21 09:28
4 个月前
此快照最后确认于
2025/11/21 09:28
4 个月前
查看原帖
才学OI 70天,不知道哪里re了啊
不是数组问题,数组再大就MLE了
我已经开启低智模式,打这题特困,望思路清晰的dalao帮我调错
CPP
#include<iostream>
#include<cmath>
#include<cstring>
#include<cstdio>
#include<algorithm>
#define MN 2000005
#define re register int
#define ll long long
using namespace std;
int f[MN],v[MN],s[MN],r[MN],son[MN][2];
int bcj[MN];
int zhan[MN];
int n,m,cnt;
int vis[MN];
struct caozuo{
int k,a,b;
}cz[MN];
struct tu{
int u,v,w;
bool operator<(tu x)const{
	return w<x.w;
}
}e[MN];
int getbcj(int x){
	if(x==bcj[x])return bcj[x];
	bcj[x]=getbcj(bcj[x]);
	return bcj[x];
}
int bz[1001][1001];
//令人大雾的邻接矩阵
int get(int x){////判断节点是否为一个Splay的根(与普通Splay的区别1)
	return son[f[x]][0]==x||son[f[x]][1]==x;
}////如果连的是轻边,他的父亲的儿子里没有它
void pushup(int x){
	s[x]=x;
    if(v[s[x]]<v[s[son[x][0]]])s[x]=s[son[x][0]];
    if(v[s[x]]<v[s[son[x][1]]])s[x]=s[son[x][1]];
}
void filp(int x){
	swap(son[x][0],son[x][1]);
	r[x]^=1;
}
void pushdown(int x){
	if(!r[x])return;
	r[x]=0;
	if(son[x][0])filp(son[x][0]);
	if(son[x][1])filp(son[x][1]);
}
void rotate(int x){
	int y=f[x],z=f[y],k=(son[y][1]==x),s=son[x][!k];
	if(get(y))son[z][son[z][1]==y]=x;son[x][!k]=y;son[y][k]=s;
	if(s)f[s]=y;f[y]=x;f[x]=z;
	pushup(y);
}
void splay(int x){
	int y=x,top=0;
	zhan[++top]=y;
	while(get(y))zhan[++top]=f[y],y=f[y];
	while(top)pushdown(zhan[top--]);
	while(get(x)){
		y=f[x],top=f[y];
		if(get(y))
		rotate((son[y][0]==x)^(son[top][0]==y)?x:y);
		rotate(x);
	}
	pushup(x);
	return;
}
void access(int x){
	for(re y=0;x;y=x,x=f[x]){
	splay(x);
	son[x][1]=y;
	pushup(x);
	}
}
void makeroot(int x){
	access(x);
	splay(x);
	filp(x);
}
int findroot(int x){	
	access(x);
	splay(x);
	while(son[x][0])pushdown(x),x=son[x][0];
	splay(x);
	return x;
}
void split(int x,int y){
	makeroot(x);
	access(y);
	splay(y);
}
void cut(int x,int y){
	split(x,y);
	if(findroot(y)==x&&f[y]==x&&!son[y][0]){
	f[y]=son[x][1]=0;
	pushup(x);
	}
	return;
		
} 
void link(int x,int y){
	makeroot(x);
	if(findroot(y)!=x)
	f[x]=y;
}
 void kruskal(){
    for(re i=1;i<=m;i++){
        int fx=getbcj(e[i].u),fy=getbcj(e[i].v);
        if(!vis[i]&&fx!=fy)
            link(e[i].u,i+n),link(e[i].v,i+n),bcj[fx]=fy;
    }
}

int main(){
	int t;
	int xx[MN],yy[MN];
	scanf("%d%d%d",&n,&m,&t);
	for(re i=1;i<=m;i++){
	scanf("%d%d%d",&e[i].u,&e[i].v,&e[i].w);
	bz[e[i].u][e[i].v]=bz[e[i].v][e[i].u]=i+n;
	v[i+n]=e[i].w;
	xx[i+n]=e[i].u;
	yy[i+n]=e[i].v;
	}	
	for(re i=1;i<=t;i++){
	scanf("%d%d%d",&cz[i].k,&cz[i].a,&cz[i].b);
	if(cz[i].k==2)vis[bz[cz[i].a][cz[i].b]]=vis[bz[cz[i].b][cz[i].a]]=1;
	}
	for(re i=1;i<=n;i++)
	bcj[i]=i;

	kruskal();
	int ans[MN],tot1=0;
	for(re i=t;i>=1;i--){
	if(cz[i].k==1)
	split(cz[i].a,cz[i].b),ans[++tot1]=v[s[cz[i].b]];
	else {
		split(cz[i].a,cz[i].b);
		if(v[s[cz[i].b]]>v[s[bz[cz[i].a][cz[i].b]]]){
			cut(yy[s[cz[i].b]],s[cz[i].b]);cut(xx[s[cz[i].b]],s[cz[i].b]);
			link(bz[cz[i].a][cz[i].b],cz[i].a);
			link(bz[cz[i].a][cz[i].b],cz[i].b);
		}
}
}
	for(re i=tot1;i>=1;i--)
		printf("%d\n",ans[i]);


	return 0;
}

回复

8 条回复,欢迎继续交流。

正在加载回复...