POJ 2236 解题报告

来源:互联网 发布:清华 王奇 知乎 编辑:程序博客网 时间:2024/06/04 01:22

这道题是并查集(union-find)应用。知道后就简单了。之前已经多次写过了。这里用的是之前1703的程序。

刚开始用的DFS搜索,超时了,看了discuss才知道是并查集。

thestoryofsnow2236Accepted196K1079MSC++1957B

/* ID: thestor1 LANG: C++ TASK: poj2236 */#include <iostream>#include <fstream>#include <cmath>#include <cstdio>#include <cstring>#include <limits>#include <string>#include <vector>#include <list>#include <set>#include <map>#include <queue>#include <stack>#include <algorithm>#include <cassert>using namespace std;const int MAXN = 1001;void makeset(const int N, vector<int> &parent, vector<int> &rank){for (int u = 0; u < N; ++u){parent[u] = u;rank[u] = 0;}}int find(int u, vector<int> &parent){if (parent[u] != u){parent[u] = find(parent[u], parent);}return parent[u];}void union_set(int u, int v, vector<int> &parent, vector<int> &rank){int ru = find(u, parent);int rv = find(v, parent);if (ru == rv){return;}if (rank[ru] < rank[rv]){parent[ru] = rv;}else if (rank[rv] < rank[ru]){parent[rv] = ru;}else{parent[ru] = rv;rank[rv]++;}}int main(){int computers[MAXN][2];bool repired[MAXN];int N, D;scanf("%d%d", &N, &D);int D2 = D * D;for (int i = 0; i < N; ++i){scanf("%d%d", &computers[i][0], &computers[i][1]);}for (int i = 0; i < N; ++i){repired[i] = false;}vector<int> parent(N), rank(N);makeset(N, parent, rank);char type;while (scanf(" %c", &type) > 0){if (type == 'O'){int p;scanf("%d", &p);p--;for (int i = 0; i < N; ++i){if (repired[i]){int d2 = (computers[p][0] - computers[i][0]) * (computers[p][0] - computers[i][0]) + (computers[p][1] - computers[i][1]) * (computers[p][1] - computers[i][1]);if (d2 <= D2){union_set(p, i, parent, rank);}}}repired[p] = true;}else if (type == 'S'){int p, q;scanf("%d%d", &p, &q);p--, q--;if (repired[p] && repired[q] && find(p, parent) == find(q, parent)){printf("SUCCESS\n");}else{printf("FAIL\n");}}}return 0;  }


0 0
原创粉丝点击