题意:给你n台电脑的坐标,一个距离d,这个d的意思是如果两台电脑的距离小于等于d,那么他们可以连接在一起,其中a连b,b连c,那么c可以连a,起初这几台电脑都是坏的,之后给你一组操作,O a,表示修复a这台电脑(它可以和其他好的且距离小于d的电脑连接),S a b 是询问a和b这两台电脑是不是连接在一起,如果是输出成功,如果不是输出失败
思路:分析一下这道题,那就是我们现在有一堆电脑,在修复电脑a的过程中,如果他周围的电脑和a的距离小于d那么我们可以将他们连接在一起(并),之后我们还要查找a,b是否连接,也就是说a,b是不是在一个集合里面(查),嗯,没错裸的并查集,唯一有新意的地方就是在合并a,b的时候要看一下a和b是否都修复了并且a,b的距离是否比d小就好了,上代码吧:
#include <stdio.h>
#include <string.h>
#include <algorithm>
#include <math.h>
#include <iostream>
using namespace std;
struct node
{
double x,y;
}edg[1101];
double dist[1101][1101] , vis[1101];
int p[1101];
int n,d;
int getf(int x)
{
return x == p[x] ? x : p[x] = getf(p[x]);
}
void init()
{
for(int i = 0 ; i < 1101 ; i++)
{
p[i] = i;
}
}
void merge(int x,int y)
{
int dx = getf(x);
int dy = getf(y);
//printf("P = %lf\n",distc(edg[x],edg[y]));
if(dx != dy)
{
// printf("dx = %d dy = %d\n",dx,dy);
p[dy] = dx;
}
}
int main()
{
while(scanf("%d%d",&n,&d)!=EOF)
{
init();
for(int i = 1 ; i <= n ; i++)
{
scanf("%lf%lf",&edg[i].x,&edg[i].y);
}
for(int i = 1 ; i <= n ; i++)//先把所有的距离都打到一个表上
{
for(int j = 1 ; j <= n ;j++)
{
dist[i][j] = sqrt((edg[i].x-edg[j].x) * (edg[i].x-edg[j].x) + (edg[i].y - edg[j].y) * (edg[i].y - edg[j].y));
}
}
char op[3];
memset(vis,0,sizeof(vis));
while(scanf("%s",op)!=EOF)
{
int a,b;
if(op[0] == 'O')
{
scanf("%d",&a);
vis[a] = 1;//如果a修复了就打上标记
for(int i = 1 ; i <= n ; i++)
{
if(vis[i] && i!=a)//如果i也被修复了且i和a的距离小于等于d就表明他们可以合并到一个集合里
{
if(dist[i][a] <= d)
{
merge(a,i);
}
}
}
}
else
{
scanf("%d%d",&a,&b);
if(getf(a) == getf(b))
{
puts("SUCCESS");
}
else
{
puts("FAIL");
}
}
}
}
}
这是把所有距离都打成表的写法,其实没必要打个一个表,在合并的时候判断一下就好了,也都一样,
#include <stdio.h>
#include <string.h>
#include <algorithm>
#include <math.h>
#include <iostream>
using namespace std;
struct node
{
double x,y;
}edg[1101];
double dist[1101][1101] , vis[1101];
int p[1101];
int n,d;
double distc(node a,node b)
{
double dist;
dist=sqrt((double)((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y)));
return dist;
}
int getf(int x)
{
return x == p[x] ? x : p[x] = getf(p[x]);
}
void init()
{
for(int i = 0 ; i < 1101 ; i++)
{
p[i] = i;
}
}
void merge(int x,int y)
{
int dx = getf(x);
int dy = getf(y);
if(distc(edg[x],edg[y]) <= d)
{
if(dx != dy)
{
p[dy] = dx;
}
}
}
int main()
{
while(scanf("%d%d",&n,&d)!=EOF)
{
init();
for(int i = 1 ; i <= n ; i++)
{
scanf("%lf%lf",&edg[i].x,&edg[i].y);
}
char op[3];
memset(vis,0,sizeof(vis));
while(scanf("%s",op)!=EOF)
{
int a,b;
if(op[0] == 'O')
{
scanf("%d",&a);
vis[a] = 1;
for(int i = 1 ; i <= n ; i++)
{
if(vis[i] && i!=a)
merge(a,i);
}
}
else
{
scanf("%d%d",&a,&b);
if(getf(a) == getf(b))
{
puts("SUCCESS");
}
else
{
puts("FAIL");
}
}
}
}
}