P2307 迷宫 并查集求解

本文介绍了如何使用并查集数据结构处理不连续输入的数据,通过初始化、路径压缩和判断连通性来确保问题的有效解决。关键步骤包括记录数据范围、检查father节点一致性,以及在输入每组数据后进行路径查找。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

记录一下求解代码
思路

  1. 并查集作为工具,每次输入新的一组数据时将所有辅助空间重置
  2. menton数组,minX,maxX来记录输入数据的最大值,最小值以及输入过的数据,因为数据输入并不是从一开始也不是n-m连续的
  3. 对于每一组数据 输入的每一对数据,先检验是否二者father是否相同,相同说明已经连通,再联通便会有两条路不符合题意,不同便进行连接。
  4. 输入完每组数据后,再次进行运行find函数,进行路径压缩。检查每个节点的father是否一致,不一致说明不符合题意。
//
// Created by 29273 on 2022-03-09.
//
#include "bits/stdc++.h"

using namespace std;
const int maxN = 1e3 + 10;
int n, m, flag;
int father[maxN], minX, maxX;
bool mention[maxN];

void Init() {
    for (int i = 0; i < maxN; ++i) {
        father[i] = i;
    }
    memset(mention, 0, sizeof mention);
    minX = 100001;
    maxX = 1;
    flag = 1;
}

int find(int x) {
    int r = x;
    while (r != father[r]) //寻找根结点
        r = father[r];
    int i = x, j;
    while (father[i] != r) //路径压缩
    {
        j = father[i];
        father[i] = r;
        i = j;
    }
    return r;
}

void Union(int x, int y) {
    int dx = find(x);
    int dy = find(y);
    if (dx != dy) {
        father[dx] = dy;
    }
}


int main() {
    Init();
    while (scanf("%d %d", &n, &m) == 2) {
        if (n == -1 && m == -1) break;
        if (n == 0 && m == 0) {
            for (int i = minX; i <= maxX; i++) {
                if (mention[i]) {
                    find(i);
                }
            }
            int fa = father[minX];
            for (int i = minX + 1; i <= maxX; ++i) {
                if (mention[i] && father[i] != fa) {
                    flag = 0;
                    break;
                }
            }
            if (flag)
                printf("1\n");
            else
                printf("0\n");
            Init();
        } else {
            mention[n] = 1;
            mention[m] = 1;
            minX = min(minX, min(n, m));
            maxX = max(maxX, max(n, m));
            if (find(n) != find(m)) {
                Union(n, m);
            } else {
                flag = 0;
            }
        }

    }
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值