做这套题之前一直以为并查集是很简单的数据结构。
做了才发现自己理解太不深刻。只看重片面的合并集合。。
重要的时发现每个集合的点与这个根的关系,这个关系可以做太多事情了。
题解:
POJ 2236 Wireless Network
10S时限,尽量做到最优吧。一开始还怕会T
预处理出能到达的点。简单题看代码就行了
#include <map> #include <set> #include <list> #include <cmath> #include <ctime> #include <deque> #include <stack> #include <queue> #include <cctype> #include <cstdio> #include <string> #include <vector> #include <climits> #include <cstdlib> #include <cstring> #include <iostream> #include <algorithm> #define LL long long #define PI 3.1415926535897932626 using namespace std; int gcd(int a, int b) {return a % b == 0 ? b : gcd(b, a % b);} const int MAXN = 1010; struct point { double x,y; }src[MAXN]; int fa[MAXN]; int Find(int x) {return x == fa[x] ? x : fa[x] = Find(fa[x]);} bool repair[MAXN]; double dis[MAXN][MAXN]; vector<int>go[MAXN]; int main() { int N; double D; scanf("%d%lf",&N,&D); for (int i = 1 ; i <= N ; i++) scanf("%lf%lf",&src[i].x,&src[i].y); for (int i = 1 ; i <= N ; i++) go[i].clear(); for (int i = 1 ; i <= N ; i++) fa[i] = i; for (int i = 1 ; i <= N ; i++) { for (int j = i + 1 ; j <= N ; j++) { dis[i][j] = sqrt((src[i].x - src[j].x) * (src[i].x - src[j].x) + (src[i].y - src[j].y) * (src[i].y - src[j].y)); dis[j][i] = dis[i][j]; if (dis[i][j] <= D) go[i].push_back(j); if (dis[i][j] <= D) go[j].push_back(i); } } memset(repair,false,sizeof(repair)); char op[5]; while (scanf("%s",op) != EOF) { if(op[0] == 'O') { int x; scanf("%d",&x); repair[x] = true; for (int j = 0 ; j < (int)go[x].size() ; j++) { if (repair[go[x][j]]) { int fx = Find(x); int fy = Find(go[x][j]); if (fx != fy) fa[fx] = fy; } } } else { int x,y; scanf("%d%d",&x,&y); int fx = Find(x); int fy = Find(y); if (fx == fy) puts("SUCCESS"); else puts("FAIL"); } } return 0; }