题目链接:http://poj.org/problem?id=2236
首先先说一下一个坑点,,现在还不知道为啥,一开始是TLE,我找了很久,没有发现错误,后来想到以前poj的尿性,想到可能是一组输入,于是我就改成了一组输入,莫名其妙就ac了,按道理来说应该即使只有一组输入,我写出while(scanf....)也会只读入一组输入的,不应该出现TLE情况的!
这道题题意就是有多个通讯点,在他们好用和相互之间距离小于等于d的情况下,可以相互通讯!而一开始全部损坏了,经过一系列操作,有修复和查询问你查询后是否能够通讯的结果!
首先我们可以分析出来,有300000行,每一次暴力你都需要遍历原来已经修复好的通讯点,0(N2)的复杂度是肯定不能过的!那么就需要用到并查集!在这道题中,哪些条件适用于并查集的处理!
并查集其实就是集合的合并和查询!!处理只有合并!那么在这道题的输入中,每次都会输入修复的点,其实就是告诉我们在合并修复点的集合!而后面的查询操作其实也就是不正是可以看出集合的查询吗!我们修复了的点满足了距离要求的话,我们就可以给它加入到集合中取,通过路径压缩,后面的查询是0(1)级别的,时间上能够通过!下面画一下图看看什么是路径压缩!
就是说通过路径压缩后,在一个findd函数后,集合中始终只会有俩层,那么你下次查询的时候,一下子就能找到父亲结点!!
代码如下:
#include <cstdio> #include <cstring> #include <string> #include <iostream> #include <algorithm> #include <stack> #include <queue> #include <map> #include <vector> #include <cmath> #define lson l,m,rt<<1 #define rson m+1,r,rt<<1|1 using namespace std; const int maxn = 1111; int pre[maxn]; int vis[maxn]; void init() { for (int i = 0; i<maxn; i++) pre[i] = i; //自己的父亲是自己,孤立一点 } int findd(int n) { if (n == pre[n]) return n; else return pre[n] = findd(pre[n]); } void unionn(int u, int v) //整个集合中始终只有一个父亲 { int fu = findd(u); int fv = findd(v); pre[fu] = fv; } struct node { int x, y; node() {} node(int x, int y) :x(x), y(y) {} }node1[maxn]; int d; bool distance1(node a, node b) { if ((a.x - b.x)*(a.x - b.x) + (a.y - b.y)*(a.y - b.y) <= d*d) return true; else return false; } int main(void) { //freopen("in.txt", "r", stdin); //你需要记录哪些是已经修复好了的 int N, i, j; //while (scanf("%d%d", &N, &d)) //这里无法理解,我变成了一组输入就过了,多组输入就过不了 //{ scanf("%d%d", &N, &d); init(); for (i = 1; i<=N; i++) { int x, y; scanf("%d%d", &x, &y); node1[i] = node(x, y); } string op; int xx, yy; memset(vis, 0, sizeof(vis)); while (cin >> op) { if (op[0] == 'O') { scanf("%d", &xx); //你要知道,哪些结点是已经修复好的,所以用一个数组来维护 vis[xx] = 1; //vis来记录哪些结点是已经修复好了的,用一个数组来维护 for (i = 1; i <= N; i++) { if (vis[i]&&distance1(node1[i],node1[xx])&&i!=xx) //找原来已经修复好了,并且能够满足由于硬件条件距离限制的通讯设备 { unionn(i, xx); } } } else { scanf("%d%d", &xx, &yy); if (findd(xx) == findd(yy)) printf("SUCCESS\n"); else printf("FAIL\n"); } } //} return 0; }