并查集简单题

The Suspects

题目传送:POJ-1611-The Suspects

AC代码:

#include <map>
#include <set>
#include <cmath>
#include <deque>
#include <queue>
#include <stack>
#include <cstdio>
#include <cctype>
#include <string>
#include <vector>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
#define LL long long
#define INF 0x7fffffff
using namespace std;

int n, m;
const int maxn = 30005;
int pa[maxn];
int tot[maxn];//记录当前集合的总数 

int find(int x) {
    return pa[x] == x ? x : pa[x] = find(pa[x]);//带路径压缩
}

void link(int x, int y) {
    int px = find(x);
    int py = find(y);
    if(px == py) return;
    pa[px] = py;
    tot[py] += tot[px];
}

int main() {
    while(scanf("%d %d", &n, &m) != EOF) {
        if(n == 0 && m == 0) break;

        for(int i = 0; i <= n; i ++) {
            pa[i] = i;
            tot[i] = 1;
        }

        int k, h, s;
        for(int i = 0; i < m; i ++) {
            scanf("%d", &k);
            scanf("%d", &h);
            for(int j = 1; j < k; j ++) {
                scanf("%d", &s);
                link(h, s);
            }
        }

        printf("%d\n", tot[find(0)]);
    }
    return 0;
}

Cube Stacking

题目传送:POJ - 1988 - Cube Stacking

AC代码:

#include <map>
#include <set>
#include <cmath>
#include <deque>
#include <queue>
#include <stack>
#include <cstdio>
#include <cctype>
#include <string>
#include <vector>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
#define LL long long
#define INF 0x7fffffff
using namespace std;

const int maxn = 30005;
int pa[maxn];
int under[maxn];
int sum[maxn];

int p;

int find(int x) {
    if(x == pa[x]) {
        return x;
    }
    int t = find(pa[x]);
    under[x] += under[pa[x]];//路径压缩的时候要更新under数组,且这个数组只能放这里,因为要先更新祖先
    pa[x] = t;
    return pa[x];
}

void link(int x, int y) {//把x所在的堆放到y所在的堆上
    int px = find(x);
    int py = find(y);
    if(px == py) {
        return;
    }
    pa[px] = py;
    under[px] = sum[py];//将下面那个堆的总数更新到上面那个堆的根
    sum[py] += sum[px];//计算现在这个堆的总数,不能和上面那个位置互换
}

int main() {
    while(scanf("%d", &p) != EOF) {

        for(int i = 0; i < maxn; i ++) {
            pa[i] = i;
            under[i] = 0;
            sum[i] = 1;
        }

        char op[15];
        int a, b;
        for(int i = 0; i < p; i ++) {
            scanf("%s", op);
            if(op[0] == ‘M‘) {
                scanf("%d %d", &a, &b);
                link(a, b);
            }
            else {
                scanf("%d", &a);
                find(a);
                printf("%d\n", under[a]);
            }
        }
    }
    return 0;
}

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-10-07 11:13:51

并查集简单题的相关文章

POJ2236 wireless network 【并查集水题】

前端开发whqet,csdn,王海庆,whqet,前端开发专家 今天是个好日子,2014年5月20日,表白的最佳时机,虽说孩子已经四岁.结婚已经五年,但是也不可以偷懒,于是有了这个效果. 在线研究点这里,下载收藏点这里.程序猿and程序媛,大胆秀出你的爱吧. 利用html5 canvas实现动态的文字粒子效果,效果如下. OK,简单看看原理,首先我们需要在canvas里面实现描边文字,然后利用getImageData获得描边文字的像素矩阵,将粒子效果绑定在描边文章上. 整个效果如下. html文

poj1611(并查集简单应用)

题目链接:http://poj.org/problem?id=1611 思路: 显然是一个并查集的题,很简单,只要将一个group中的学生并在一起,最后遍历1到n-1,看有多少学生的祖先与0的祖先相等即可. 代码如下: 1 #include<cstdio> 2 using namespace std; 3 4 int n,m,res,root[30005]; 5 6 int getr(int k){ 7 if(root[k]==k) return k; 8 else return root[k

G - Brain Network (easy)(并查集水题)

G - Brain Network (easy) Time Limit:2000MS     Memory Limit:262144KB     64bit IO Format:%I64d & %I64u CodeForces 690C1 Description One particularly well-known fact about zombies is that they move and think terribly slowly. While we still don't know

poj 1182 食物链 并查集好题

挑战程序设计上有解答的并查集好题.把事件作为元素进行合并,举例:若输入1 2 3,意思就是把2,3归为同一类,至于归于哪一类并不需要去讨论,则把2属于A,3属于A这两件事件归为一类;2属于B,3属于B这两件事归为一类;2属于C,3属于C这两件事归为一类:若输入 2 2 3,由于A吃B,B吃C,C吃A,就把2属于A,3属于B这两件事情归为一类:以此类推.当检测到当前情况与之前正确的情况不符合,则错误的情况数加1. #include <iostream> #include <cstdio&g

【HDU1232】畅通工程(并查集基础题)

裸敲并查集,很水一次AC 1 #include <iostream> 2 #include <cstring> 3 #include <cstdlib> 4 #include <cstdio> 5 #include <cctype> 6 #include <cmath> 7 #include <algorithm> 8 #include <numeric> 9 #include <string> 1

【HDU1856】More is better(并查集基础题)

裸并查集,但有二坑: 1.需要路径压缩,不写的话会TLE 2.根据题目大意,如果0组男孩合作的话,应该最大的子集元素数目为1.所以res初始化为1即可. 1 #include <iostream> 2 #include <cstring> 3 #include <cstdio> 4 #include <cstdlib> 5 #include <algorithm> 6 #include <numeric> 7 #include <

【HDU1325】Is It A Tree?(并查集基础题)

有以下坑点: 1.结束输入不一定-1,题目中的叙述只是说所有权值都为正值. 2.是否构成一棵树不能只判断是否只有一个根节点,没有环路,而且还需要判断每个节点的入度一定是1,不然就不是一棵树. (无环路也可用树的性质:结点数 = 边树 + 1 来取代) 1 #include <iostream> 2 #include <cstdlib> 3 #include <cstring> 4 #include <cctype> 5 #include <cmath&

UVALive 4487 Exclusive-OR 加权并查集神题

已知有 x[0-(n-1)],但是不知道具体的值,题目给定的信息 只有 I P V,说明 Xp=V,或者 I P Q V,说明 Xp ^ Xq=v,然后要求回答每个询问,询问的是 某任意的序列值 Xp1^Xp2,,,,X^pk 这个题目用加权并查集是这么处理的: 1. f[]照样是代表父节点,照样进行路径压缩,把每个 V[i]=V[i]^V[f[i]],即节点存储的值实际是它与它父亲的异或的值.为什么要这样呢,因为异或首先满足交换律,而且异或同一个数偶数次,即相当于本身,那么这个题目的其中一个要

【HDU2120】Ice_cream&#39;s world I(并查集基础题)

查环操作,裸题.一次AC. 1 #include <iostream> 2 #include <cstring> 3 #include <cstdlib> 4 #include <cctype> 5 #include <cmath> 6 #include <string> 7 #include <cstdio> 8 #include <algorithm> 9 #include <numeric>