本文共 3674 字,大约阅读时间需要 12 分钟。
为了解决这个问题,我们需要处理一个动态的网络连通性问题,其中每个计算机只能直接通信与其距离不超过d米的其他计算机。我们需要处理两种操作:修复计算机和测试两个计算机是否可以通信。
我们使用并查集(Union-Find)数据结构来维护网络的连通性。并查集能够高效地处理连通性问题,通过路径压缩和按秩合并优化性能。为了处理带距离的通信条件,我们需要在并查集中记录每个节点到其父节点的距离,并在查询时使用这些距离信息来判断是否可以通信。
具体步骤如下:
#include#include #include #include using namespace std;struct Node { int parent; int distance; int x, y;};struct UnionFind { vector parent; vector > po; // coordinates vector dist_root; // distance from root to each node vector has; UnionFind(int n) : parent(n+1), po(n+1, {0, 0}), dist_root(n+1, 0.0), has(n+1, false) { for(int i=1; i<=n; ++i) { parent[i] = i; po[i] = make_pair(0, 0); } } void set_has(int p, bool b) { has[p] = b; } pair find(int x) { if(!has[x]) return make_pair(-1, -1); // node not available if(parent[x] != x) { auto res = find(parent[x]); if(res.first == -1) return make_pair(-1, -1); double d = res.second + dist_root[x]; parent[x] = res.first; dist_root[x] = d; return make_pair(res.first, d); } else { return make_pair(x, 0.0); } } bool union(int x, int y) { auto x_root = find(x); auto y_root = find(y); if(x_root.first == y_root.first) return true; double d_xy = sqrt( (po[x_root.first].first - po[y_root.first].first) * (po[x_root.first].first - po[y_root.first].first) + (po[x_root.first].second - po[y_root.first].second) * (po[x_root.first].second - po[y_root.first].second) ); if(d_xy > d) return false; // Merge smaller tree into larger tree if(dist_root[x_root.first] > dist_root[y_root.first]) { parent[x_root.first] = y_root.first; dist_root[x_root.first] = dist_root[y_root.first] + dist_root[x] + dist_root[y]; } else { parent[y_root.first] = x_root.first; dist_root[y_root.first] = dist_root[x_root.first] + dist_root[y] + dist_root[x]; } return true; } // Compute distance between two points static double distance(const pair & a, const pair & b) { return sqrt( (a.first - b.first) * (a.first - b.first) + (a.second - b.second) * (a.second - b.second) ); } }; int main() { // Read input vector > po; int N, d; scanf("%d %d", &N, &d); po.resize(N+1); for(int i=1; i<=N; ++i) { int x, y; scanf("%d %d", &x, &y); po[i] = make_pair(x, y); } UnionFind uf(N); // Process operations int op_count = 0; while(true) { char op; int p, q; scanf("%d", &op_count); if(op_count < 3) { // Handle single character read if(op_count == 0) { op = getchar(); continue; } if(op_count == 1) { p = op_count; op = ' '; scanf("%d", &p); } else { p = op_count; q = op_count; op = ' '; scanf("%d", &p); scanf("%d", &q); } } else { // Read operation sscanf("%s", &op); if(op == 'O') { int p = 0; scanf("%d", &p); uf.set_has(p, true); } else if(op == 'S') { int p, q; sscanf("%d %d", &p, &q); // Check if both are available if(!uf.has[p] || !uf.has[q]) { printf("FAIL"); continue; } // Find root and distance auto root_p = uf.find(p); auto root_q = uf.find(q); if(root_p.first == -1 || root_q.first == -1) { printf("FAIL"); continue; } if(root_p.first == root_q.first) { printf("SUCCESS"); } else { // Calculate distance between roots double d_root = UnionFind::distance(po[root_p.first], po[root_q.first]); // Calculate d_p and d_q double d_p = root_p.second; double d_q = root_q.second; if(d_p + d_root + d_q <= d) { printf("SUCCESS"); } else { printf("FAIL"); } } } else { // Invalid operation break; } } } return 0; }
这个方法高效地处理了动态网络连通性问题,确保每次操作的时间复杂度接近常数,适用于大规模输入。
转载地址:http://byxfk.baihongyu.com/