题意
一个计算机网络里的计算机都坏了, 现在有两种操作, “O p”代表修复了p机器, “S p q”代表检查 p, q 两台机器是否连接( 直线距离<=d或者中间有距离<=d的用来联通的机器 )
思路
比赛的时候愣是没读清楚题目意思, 还以为是什么搜索, 瞎瘠薄做了个MLE
没料到居然是个并查集, 注意应该是直线距离 <= d, 不是上下左右走的
每次修复一个机器的时候检查他与其他机器的直线距离, 并将其并入集合中
查找的时候寻找根节点就ojbk
读题没读明白是一方面, 总的来说还是做题经验不够
AC代码
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>using namespace std;
const int maxn = 1e3 + 5;
int mrk[maxn];
int n, d;
char op[2];
struct computer{int f;int x, y;
}p[maxn];void init(){for( int i = 1; i <= maxn; i++ )p[i].f = i;return;
}int _find( int a ){if( a != p[a].f )return _find(p[a].f);return a;
}double getdis( int x1, int y1, int x2, int y2 ){double dx = fabs((double)(x1-x2));double dy = fabs((double)(y1-y2));double dis = sqrt(dx*dx+dy*dy);return dis;
}void _union( const computer a, const computer b ){int aa = _find(a.f);int bb = _find(b.f);if( aa != bb )if( getdis(a.x, a.y, b.x, b.y) <= d )p[bb].f = aa;return;
}int main()
{int a, b;init();scanf("%d%d",&n, &d);for( int i = 1; i <= n; i++ ){scanf("%d%d", &p[i].x, &p[i].y);}while( ~scanf("%s",op) ){if( op[0] == 'O' ){scanf("%d",&a);mrk[a] = 1;for(int i = 1; i <= n; i++)if( mrk[i] && i != a)_union(p[i], p[a]);}else if( op[0] == 'S' ){scanf("%d%d",&a, &b);if( _find(a) == _find(b) ) puts("SUCCESS");else puts("FAIL");}}return 0;
}