博客
关于我
poj 2236
阅读量:793 次
发布时间:2023-03-03

本文共 3674 字,大约阅读时间需要 12 分钟。

为了解决这个问题,我们需要处理一个动态的网络连通性问题,其中每个计算机只能直接通信与其距离不超过d米的其他计算机。我们需要处理两种操作:修复计算机和测试两个计算机是否可以通信。

方法思路

我们使用并查集(Union-Find)数据结构来维护网络的连通性。并查集能够高效地处理连通性问题,通过路径压缩和按秩合并优化性能。为了处理带距离的通信条件,我们需要在并查集中记录每个节点到其父节点的距离,并在查询时使用这些距离信息来判断是否可以通信。

具体步骤如下:

  • 初始化:读取输入数据,初始化并查集结构,每个计算机的父节点为自己,距离为0。
  • 修复操作:将指定的计算机标记为可用状态。
  • 测试操作:检查两个计算机是否都被修复。如果都被修复,使用并查集查找它们的根节点和距离,判断是否满足通信条件。
  • 解决代码

    #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/

    你可能感兴趣的文章
    POI:POI实现docx文件添加水印
    查看>>
    POJ 1006
    查看>>
    Quartz中时间表达式的设置-----corn表达式
    查看>>
    poj 1035
    查看>>
    POJ 1061 青蛙的约会 (扩展欧几里得)
    查看>>
    Quartz2.2.1简单使用
    查看>>
    POJ 1080 Human Gene Functions(DP:LCS)
    查看>>
    Quant 开源项目教程
    查看>>
    POJ 1088 滑雪
    查看>>
    POJ 1095 Trees Made to Order
    查看>>
    POJ 1113 Wall(计算几何--凸包的周长)
    查看>>
    poj 1125Stockbroker Grapevine(最短路)
    查看>>
    Qualitor processVariavel.php 未授权命令注入漏洞复现(CVE-2023-47253)
    查看>>
    poj 1151 (未完成) 扫描线 线段树 离散化
    查看>>
    POJ 1151 / HDU 1542 Atlantis 线段树求矩形面积并
    查看>>
    poj 1163 数塔
    查看>>
    POJ 1177 Picture(线段树:扫描线求轮廓周长)
    查看>>
    Qualitor checkAcesso.php 任意文件上传漏洞复现(CVE-2024-44849)
    查看>>
    POJ 1182 食物链(并查集拆点)
    查看>>
    POJ 1185 炮兵阵地 (状态压缩DP)
    查看>>