萌新第一次做紫题求助
查看原帖
萌新第一次做紫题求助
506081
BlueSky_楼主2021/7/5 16:04

用的并查集思路,加上邻接表判断顺序先后(虽然是TLE的)

#include<bits/stdc++.h>
using namespace std;

int n,m,a[202000],s[202000],fa[202000],l[202000][100],nd[2020000],X,Y;//邻接表 
char c;

int fin(int x){	//主元 
	if(fa[x]==x) return x;
	return fin(fa[x]);
}

int q(int x,int son,int p){	//求和
	if(x==son) return p;
	int cnt=1;
	while(l[x][cnt]!=son) cnt++;
	cnt++;
	for(;cnt<=nd[x];cnt++) p+=s[l[x][cnt]];
	return q(fa[x],x,p);
}

void M(int x,int y){
	int u,v;
	u=fin(x),v=fin(y);
	if(u==v) return;
	fa[u]=v;
	l[v][++nd[v]]=u;
	s[v]+=s[u];
}

void D(int x,int son){
	if(x==son) return;
	int cnt=1,u;
	while(l[x][cnt]!=son) cnt++;
	u=cnt;
	cnt++;
	for(;cnt<=nd[x];cnt++){
		fa[l[x][cnt]]=X;
		s[X]+=s[l[x][cnt]];
		l[X][++nd[X]]=l[x][cnt];
	}
	nd[x]=u;
	s[x]-=s[X];
	D(fa[x],x);
}

int Q(int x,int y){
	if(fin(x)!=fin(y)) return -1;
	int u=q(fa[x],x,s[x]),v=q(fa[y],y,s[y]);
	if(u>v) return u-v+a[y];
	return v-u+a[x];
}

int main(){
	cin>>n>>m;
	for(int i=1;i<=n;i++) cin>>a[i];
	for(int i=1;i<=n;i++) s[i]=a[i],fa[i]=i;
	for(int i=1;i<=m;i++){
		cin>>c;
		if(c=='M'){
			cin>>X>>Y;
			M(X,Y);
		}else if(c=='D'){
			cin>>X;
			D(fa[X],X);
			fa[X]=X;
		}else{
			cin>>X>>Y;
			cout<<Q(X,Y)<<endl;
		}
	}
	return 0;
}

2021/7/5 16:04
加载中...