您好,欢迎来到99网。
搜索
您的当前位置:首页ACM_基础并查集

ACM_基础并查集

来源:99网

基础并查集: 用于高效的查找某两个元素是否属于同一个集合;

一.普通的查找方式:

然后每次只需要判断一下是否find(x) == find(y)如果是说明他们是同一个集合, 否则不同集合;

二.并查集的实现方式:

  • 和上面的方法大致相同, 唯一不同的是find函数; 每次find之后都把该集合的该支链的所有元素的父亲改成根节点;这样下次再find的时候只需要找一次就知道该元素属于哪个集合了;实现的方式也很相同,只需要把find函数稍微改一下:
    int find(int x){
    return x == pa[x] ? x : pa[x] = find(pa[x]);
    }

例子

题目链接:
题目大意: 中文就不解释了;
做法:把同一个集合的所有元素都放到同一个集合里, 当放完之后, 检查一下0号同学在哪个集合, 再判断一下剩下的同学是否和它在同一个集合里面;

//
//  Created by fkjs on 2015-09-17
//  Copyright (c) 2015 fkjs. All rights reserved.
//
//#pragma comment(linker, "/STACK:1024000000,1024000000")
#include <algorithm>
#include <cctype>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iomanip>
#include <iostream>
#include <map>
#include <queue>
#include <string>
#include <set>
#include <sstream>
#include <stack>
#include <vector>
#define clr(x) memset(x, 0, sizeof(x))

using namespace std;
const int INF = 0x3f3f3f3f;
const int maxm = 505;
const int maxn = 30000 + 10;
typedef long long int ll;

int n, m;
int pa[maxn];

int find(int x){//并查集的基础->find函数, 它的特点就是pa[x] = find(pa[x]), 这一语句可以把该路径上的所有点的父亲都改成根节点;
    return x == pa[x] ? x : pa[x] = find(pa[x]);
}

void connect(int x, int y){//链接两个并查集
    int fa = find(x);//找到根节点, 当然找的过程中会更新路上的点;
    int fb = find(y);//同上;
    pa[fa] = fb;//链接两个集合;
}

int main(void) {
#ifdef LOCAL
    //freopen("C:\\Users\\Administrator\\Desktop\\in.txt", "r", stdin);
    //freopen("C:\\Users\\Administrator\\Desktop\\out.txt", "w", stdout);
#endif
    //ios_base::sync_with_stdio(0);

    while(scanf("%d%d", &n, &m) == 2 && (n || m)){
        for(int i = 0; i < n; i++) pa[i] = i;
        for(int i = 0; i < m; i++){
            int len; scanf("%d", &len);
            int x; scanf("%d", &x);
            int tp = x;
            for(int i = 1; i < len; i++){
                scanf("%d", &x);
                connect(x, tp);
                tp = x;
            }
        }
        int ans = 0;
        int p = find(0);//找到最初感染者所在的集合, 它的根是p;
        for(int i = 0; i < n; i++)//凡是根是p的人都被感染了;
            if(find(i) == p)
                ans++;
        printf("%d\n", ans);
    }
    return 0;
}

因篇幅问题不能全部显示,请点此查看更多更全内容

Copyright © 2019- 99spj.com 版权所有 湘ICP备2022005869号-5

违法及侵权请联系:TEL:199 18 7713 E-MAIL:2724546146@qq.com

本站由北京市万商天勤律师事务所王兴未律师提供法律服务