目录:
题目:
题意:
给出我们n个矩阵方块,并告诉我们左下角以及右上角的坐标,求一共有几个连通块。
分析:
说是求连通块,其实我们可以用并查集来解决,只需要打好判断是否连通的条件,再用并查集来看祖先是否相同即可。
思路:
1.初始化
2.枚举每个矩阵,逐个判断是否连通,连通则将他们两个在并查集中合并
3.看在并查集中,一共出现了几个不同的祖先
AC后感想:
小编的代码在洛谷上是可以AC的,但交到sslOJ上就WA了,表示很懵逼。
然后就是洛谷上的样例是错哒,小编发的题目上改了,大家可以按照上面的数据去做。
代码:
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define LL long long
using namespace std;
inline LL read() {
LL d=0,f=1;char s=getchar();
while(s<'0'||s>'9'){if(s=='-')f=-1;s=getchar();}
while(s>='0'&&s<='9'){d=d*10+s-'0';s=getchar();}
return d*f;
}
int f[7001];
int father(int i)//找祖先
{
return f[i]==i? i:f[i]=father(f[i]);//加速递归
}
void hb(int x,int y)//合并
{
int r1=father(f[x]),r2=father(f[y]);
f[r1]=r2;
}
int p[7001];
int x1[7001],x2[7001],y1[7001],y2[7001];
int main()
{
int n=read();
for(int i=1;i<=n;i++)
x1[i]=read(),y1[i]=read(),x2[i]=read(),y2[i]=read();
for(int i=1;i<=n;i++) f[i]=i;//并查集初始化
for(int i=1;i<n;i++)
for(int j=i+1;j<=n;j++)//枚举
{
//前方高能!!!@_@
if((y1[j]>=y1[i]&&y1[j]<=y2[i])
||(y2[j]>=y1[i]&&y2[j]<=y2[i])
||(x1[j]>=x1[i]&&x1[j]<=x2[i])
||(x2[j]>=x1[i]&&x2[j]<=x2[i])
||(y1[i]>=y1[j]&&y1[i]<=y2[j])
||(y2[i]>=y1[j]&&y2[i]<=y2[j])
||(x1[i]>=x1[j]&&x1[i]<=x2[j])
||(x2[i]>=x1[j]&&x2[i]<=x2[j]))
//判断是否连通
if(father(i)!=father(j)) hb(i,j);//不是同一祖先→合并
}
for(int i=1;i<=n;i++)
p[father(i)]=1;//记录祖先
int ans=0;
for(int i=1;i<=n;i++) ans+=p[i];//统计
printf("%d",ans);
return 0;
}