poj1703 Find them, Catch them(带权并查集)

本文介绍如何使用并查集解决POJ1703问题,该问题涉及判断两个成员是否属于同一帮派。文章提供了完整的代码实现,并强调了正确编写union_set函数的重要性。

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

题目链接

http://poj.org/problem?id=1703

题意

有两个帮派:龙帮和蛇帮,两个帮派共有n个人(编号1~n),输入m组数据,每组数据为D [a][b]或A [a][b],D[a][b]表示a,b属于不同的帮派,A [a][b]则让我们判断a,b是否属于一个帮派,根据判断的结果进行相应的输出。

思路

这题和poj2492很像,使用并查集解决,方法我已在poj2492的题解中写出,这里不再赘述。

代码

 1 #include <cstdio>
 2 using namespace std;
 3 
 4 const int N = 100000 + 10;
 5 int p[N];
 6 int r[N];
 7 
 8 void make_set(int n)
 9 {
10     for (int i = 1;i <= n;i++)
11     {
12         p[i] = -1;
13         r[i] = 0;
14     }
15 }
16 
17 int find_root(int x)
18 {
19     if (p[x] == -1)
20         return x;
21 
22     int t = p[x];
23     p[x] = find_root(p[x]);
24     r[x] = (r[x] + r[t]) % 2;
25     return p[x];
26 }
27 
28 void union_set(int a, int b)
29 {
30     int ra = find_root(a);
31     int rb = find_root(b);
32 
33     if (ra != rb)
34     {
35         p[ra] = rb;
36         r[ra] = (r[a] + r[b] + 1) % 2;
37     }
38 }
39 
40 int main()
41 {
42     //freopen("poj1703.txt", "r", stdin);
43     int t;
44     scanf("%d", &t);
45     while (t--)
46     {
47         int n, m;
48         scanf("%d%d", &n, &m);
49         make_set(n);
50         char c;
51         int a, b;
52         for (int i = 0;i < m;i++)
53         {
54             getchar();
55             scanf("%c%d%d", &c, &a, &b);
56             if (c == 'A')
57             {
58                 if (find_root(a) == find_root(b))    //a,b在一个集合里
59                 {
60                     if (r[a] == r[b])    //a,b为同一帮派
61                         puts("In the same gang.");
62                     else puts("In different gangs.");    //a,b为不同帮派
63                 }
64                 else puts("Not sure yet.");    //a,b不再同一集合里,故不确定
65             }
66             else union_set(a, b);
67         }
68     }
69     return 0;
70 }

注意点

1、函数union_set要写成这样:

//正确写法
void union_set(int a, int b)
{
    int ra = find_root(a);
    int rb = find_root(b);

    if (ra != rb)
    {
        p[ra] = rb;
        r[ra] = (r[a] + r[b] + 1) % 2;
    }
}

写成如下形式会MLE:

//错误写法,MLE
void union_set(int a, int b)
{
    int ra = find_root(a);
    int rb = find_root(b);

    p[ra] = rb;
    r[ra] = (r[a] + r[b] + 1) % 2;
}

2、使用scanf输入。

相似题目

1、poj2492

转载于:https://www.cnblogs.com/sench/p/7944384.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值