为什么并查集n方会超时?
查看原帖
为什么并查集n方会超时?
716721
leo12334楼主2023/1/9 14:57

蒟蒻的我写了两份代码,第一份后边五个测试点超时了,第二份照着题解里的把int改成了longlong,并把两层循环里的第二层从1到n改为从1到i,然后就神奇的过了。感觉这点优化并不算大,求助各位大佬告知原因。 这是超时的代码

#include<bits/stdc++.h>
using namespace std;
int t,x,y,z,h,n,r,fa[1001];
struct node{
	int x,y,z;
}a[1001];
long double juli(int x,int y){
	return sqrt(pow(a[x].x-a[y].x,2)+pow(a[x].y-a[y].y,2)+pow(a[x].z-a[y].z,2));
}
int find(int x){
	if(!fa[x])return x;
	else{
		int xx=find(fa[x]);
		fa[x]=xx;
		return xx;
	}
}
void init(){
	for(int i=1;i<=n;i++)
		cin>>a[i].x>>a[i].y>>a[i].z;
	for(int i=1;i<=n;i++)fa[i]=0;
	for(int i=1;i<=n;i++){
		for(int j=1;j<=n;j++){
			if(juli(i,j)<=2*r){
				int x=find(i),y=find(j);
				if(x!=y)fa[x]=y;
			}
		}
	}
}
int main(){
	cin>>t;
	while(t--){
		cin>>n>>h>>r;
		init();
		int f=0;
		for(int i=1;i<=n;i++)
		for(int j=1;j<=n;j++)
			if(a[i].z<=r&&a[j].z>=h-r)
				if(find(i)==find(j)){
					f=1;break;
				}
		if(f)puts("Yes") ;
		else puts("No");
	}
}

这是AC的代码

#include<bits/stdc++.h>
using namespace std;
#define ll long long
int t,x,y,z,n,fa[10001];
struct node{
	ll x,y,z;
}a[10001];
ll h,r;
ll juli(int x,int y){
	return (a[x].x-a[y].x)*(a[x].x-a[y].x)+(a[x].y-a[y].y)*(a[x].y-a[y].y)+(a[x].z-a[y].z)*(a[x].z-a[y].z);
}
int find(int x){
	if(!fa[x])return x;
	else{
		fa[x]=find(fa[x]);
		return fa[x];
	}
}
void init(){
	for(int i=1;i<=n;i++)
		cin>>a[i].x>>a[i].y>>a[i].z;
	for(int i=1;i<=n;i++)fa[i]=0;
	for(int i=1;i<=n;i++){
		for(int j=1;j<i;j++){
			if(juli(i,j)<=4*r*r){
				int x=find(i),y=find(j);
				if(x!=y)fa[x]=y;
			}
		}
	}
}
int main(){
	cin>>t;
	while(t--){
		cin>>n>>h>>r;
		init();
		int f=0;
		for(int i=1;i<=n;i++){
			for(int j=1;j<=n;j++)
			if(a[i].z<=r&&a[j].z>=h-r)
				if(find(i)==find(j)){
					f=1;break;
				}
			if(f)break;
		}
		if(f)puts("Yes") ;
		else puts("No");
	}
}
2023/1/9 14:57
加载中...