关于并查集的可行性
查看原帖
关于并查集的可行性
1046636
YFF1楼主2024/9/8 20:25

班上还有另一个同学也和我一样,想到了要用并查集。然后我们讨论了一下把代码改正了。但是不知道为什么这个代码是能过的(我以为会超时),有没有大佬来解答一下时间复杂度啊?

#include<bits/stdc++.h>
#define int long long
#define x first
#define y second
using namespace std;
const int N=4e5+10,inf=0x3f3f3f3f,mod=1e9+7;
typedef pair<int,int> pii;
int mp[5][N],vis[N],ans,dx[]={0,1,0,-1},dy[]={1,0,-1,0},n,m,q,x,y;
int gx(int pos){ 
	return (pos-1)/m+1;
}
int gy(int pos){ 
	return (pos-1)%m+1;
}
int ch(pii pos){
	int x=pos.x,y=pos.y;
	if(x<1||y<1||x>n||y>m) return -inf;
	return (x-1)*m+y;
}
int find(int pos,int d){
	if(mp[d][pos]==pos) return pos;
	return mp[d][pos]=find(mp[d][pos],d);
}
void solve2(int pos){
	vis[pos]=1;
	for(int i=0;i<4;i++){
		int npos=ch({gx(pos)+dx[i],gy(pos)+dy[i]});
		if(npos<0) continue;
		npos=find(npos,i);
		mp[i][pos]=npos; 
	}
}
void solve1(int pos){
	for(int i=0;i<4;i++){
		int npos=ch({gx(pos)+dx[i],gy(pos)+dy[i]});
		if(npos<0) continue;
		npos=find(npos,i);vis[npos]=1;
		solve2(npos);
		mp[i][pos]=mp[i][npos];
	}
}
signed main(){
	cin>>n>>m>>q;
	for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) for(int d=0;d<4;d++) mp[d][ch({i,j})]=ch({i,j});
	while(q--){
		cin>>x>>y;
		int pos=ch({x,y});
		if(vis[pos]) solve1(pos);
		else solve2(pos);
	}
	for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) if(!vis[ch({i,j})]) ans++;
	cout<<ans;
	return 0;
}
2024/9/8 20:25
加载中...