题意:给一系列的点,每个点以x,y轴方向进行延伸,使得一些点成为一个集合,然后求出至少需要添加几个点使得所有的点都在一个集合里面;
思路:用并查集求出现有的形成了多少个集合,然后答案就是集合数 - 1;
这里的finds函数相比以前我写的比较精简一点;
#include<bits/stdc++.h>
using namespace std;
const int maxn = 1000 + 10;
struct Node
{
int x;
int y;
}a[maxn];
int father[maxn];
//int finds(int x)
//{
// int r = x;
// while(father[r] != r)
// {
// r = father[r];
// }
// int j = x,i ;
// while( j != r)
// {
// i = father[j];
// father[j] = r;
// j = i;
// }
// return r;
//}
int finds(int x)
{
return father[x] != x ? father[x] = finds(father[x]) : x;
}
void unions(int x,int y)
{
int rx = finds(x);
int ry = finds(y);
if(rx != ry)
{
father[rx] = ry;
}
}
int n;
void Init()
{
for(int i = 1; i <= n ; i ++)
{
father[i] = i;
}
}
int main()
{
while( ~ scanf("%d",&n) )
{
Init();
for(int i = 1; i <= n ; i ++)
scanf("%d%d",&a[i].x ,&a[i].y);
for(int i = 1; i <= n ; i ++)
{
for(int j = 1; j < i ; j ++)
{
if((a[i].x == a[j].x || a[i].y == a[j].y) && (finds(i) != finds(j)) )
{
unions(i,j);
}
}
}
set<int>s;
for(int i = 1; i <= n ; i ++)
{
s.insert(finds(i));
}
cout << s.size() - 1 << endl;
}
return 0;
}
附上最近写的一些水题:
题意:给出一系列的长方体的长宽高,求出用一个还是用两个长方体能够构成的球体的体积最大;注意一点:两个的话记得长宽高中有两个相等的时候才能用在一起;
思路:对两个分析:叠加只有叠加最小的边才有意义,所以先对每个长方体长宽高进行从大到小排一下序,之后再进行结构体排序,之后相邻的判断一下能不能一起构成长方体以形成更大的球;
|
|