poj 1703(并查集)

题意:有n个人和两个阵营,给出两种操作,A a b ,询问a和b的是否在同一个阵营,如果有人未加入任何阵营输入不确定。D a b,让a和b成为不同阵营的。

题解:两种做法。

一种是把并查集扩大一倍,先给每个人一个假定的敌人,然后有D操作时把敌人加入到假定敌人的集合中,A操作判断a和b是否在同一个集合,如果不在判断对方是否在自己假定敌人的集合中,在就是敌人,否则是不确定。

#include <stdio.h>
#include <string.h>
const int N = 100005;
char str[5];
int n, m, pa[N];

int get_parent(int x) {
    return x == pa[x] ? x : pa[x] = get_parent(pa[x]);
}

int main() {
    int t;
    scanf("%d", &t);
    while (t--) {
        scanf("%d%d", &n, &m);
        int nn = 2 * n;
        for (int i = 0; i <= nn; i++)
            pa[i] = i;
        while (m--) {
            int a, b;
            scanf("%s%d%d", str, &a, &b);
            int px = get_parent(a);
            int py = get_parent(b);
            if (str[0] == ‘A‘) {
                if (px == py)
                    printf("In the same gang.\n");
                else {
                    int t1 = get_parent(a + n);
                    int t2 = get_parent(b + n);
                    if (px == t2 || py == t1)
                        printf("In different gangs.\n");
                    else
                        printf("Not sure yet.\n");
                }
            }
            else {
                int t1 = get_parent(a + n);
                int t2 = get_parent(b + n);
                if (px != py) {
                    pa[t2] = px;
                    pa[t1] = py;
                }
            }
        }
    }
    return 0;
}

另一种做法是带权并查集,用一个数组rel[i]表示人i和他集合中父亲结点的关系,1表示是同一个阵营,0表示不同阵营。每次找到a和b的祖先与和祖先的关系,然后如果是A操作,如果px==py祖先是同一个人,那么关系就可以确定,否则关系无法确定,如果是D操作,让py成为了px的父亲,就可以更新rel[px],枚举情况发现结果是a和px还有b和py的异或结果。

#include <stdio.h>
const int N = 100005;
char str[5];
int n, m, pa[N];
bool rel[N];

int get_parent(int x, bool &r) {
    r = true;
    int temp = x;
    while (temp != pa[temp]) {
        if (rel[temp] == false)
            r = !r;
        temp = pa[temp];
    }
    pa[x] = temp;//压缩路径
    rel[x] = r;
    return temp;
}

int main() {
    int t;
    scanf("%d", &t);
    while (t--) {
        scanf("%d%d", &n, &m);
        for (int i = 0; i <= n; i++) {
            rel[i] = true;
            pa[i] = i;
        }
        while (m--) {
            int a, b;
            scanf("%s%d%d", str, &a, &b);
            bool r1, r2;
            int px = get_parent(a, r1);
            int py = get_parent(b, r2);
            if (str[0] == ‘D‘) {
                pa[px] = py;
                rel[px] = r1 == r2 ? 0 : 1;//异或结果
            }
            else {
                if (px == py) {
                    if (r1 == r2)
                        printf("In the same gang.\n");
                    else
                        printf("In different gangs.\n");
                }
                else
                    printf("Not sure yet.\n");
            }
        }
    }
    return 0;
}
时间: 2024-10-15 17:48:41

poj 1703(并查集)的相关文章

POJ 2524 并查集

Ubiquitous Religions Time Limit: 5000MS Memory Limit: 65536K Total Submissions: 23580 Accepted: 11609 Description There are so many different religions in the world today that it is difficult to keep track of them all. You are interested in finding o

poj 2513 并查集,Trie(字典树), 欧拉路径

- Colored Sticks POJ - 2513 You are given a bunch of wooden sticks. Each endpoint of each stick is colored with some color. Is it possible to align the sticks in a straight line such that the colors of the endpoints that touch are of the same color?

POJ 2492 并查集扩展(判断同性恋问题)

G - A Bug's Life Time Limit:10000MS     Memory Limit:65536KB     64bit IO Format:%I64d & %I64u Submit Status Practice POJ 2492 Appoint description: Description BackgroundProfessor Hopper is researching the sexual behavior of a rare species of bugs. H

poj 1417 并查集+dp

转自:点我 题目:给出p1+p2个人,其中p1个是好人,p2个是坏人.然后有一些关系 ,a说b是好人(坏人).其中没有矛盾的,判断是否有唯一解判断哪些人是好人,哪些人是坏人. 其中比较重要的是,好人总说真话,坏人总说假话.不需要判断矛盾.唯一解 http://poj.org/problem?id=1417 其中好人说真话,坏人说假话这点很重要. 那么如果一个人说另一个人是好人,那么如果这个人是好人,说明 对方确实是好人,如果这个是坏人,说明这句话是假的,对方也是坏人. 如果一个人说另一个人是坏人

POJ 2492 并查集应用的扩展

A Bug's Life Time Limit: 10000MS Memory Limit: 65536K Total Submissions: 28651 Accepted: 9331 Description Background Professor Hopper is researching the sexual behavior of a rare species of bugs. He assumes that they feature two different genders and

poj 1984 并查集

题目意思是一个图中,只有上下左右四个方向的边.给出这样的一些边, 求任意指定的2个节点之间的距离. 就是看不懂,怎么破 1 /* 2 POJ 1984 3 并查集 4 */ 5 6 #include <stdio.h> 7 #include <string.h> 8 #include <iostream> 9 #include <algorithm> 10 #include <math.h> 11 using namespace std; 12

Wireless Network (poj 2236 并查集)

Language: Default Wireless Network Time Limit: 10000MS   Memory Limit: 65536K Total Submissions: 17602   Accepted: 7418 Description An earthquake takes place in Southeast Asia. The ACM (Asia Cooperated Medical team) have set up a wireless network wit

源哥每日一题第十八弹 poj 1182 并查集

题目链接:http://poj.org/problem?id=1182 题意:看不懂?退群吧 比平常的并查集加了一个判断集合间关系的操作: 开一个数组记录当前点所在集合的次序(第几个集合)用012表示 比较简单的思路,不过体现了并查集的精妙 #include <iostream> #include <cstring> #include <cstdio> using namespace std; int dad[500005]; int st[50005]; int fi

poj 2912 并查集(食物链加强版)

题目:给出n个人玩剪刀石头布的游戏,其中有一个人是裁判,剩下的人分为3组,每一组的人只出某一种手型,裁判可以任意出.问是否能判断出哪个人是裁判 链接:点我 分分钟看吐血,先把食物链看懂吧 枚举裁判,然后并查集判断 裁判由于可以任意出,所以可能属于任意一个集合,所以有裁判参与的会合不考虑,然后并查集部分和食物链很相似. 如果某个裁判那里出现了矛盾,则记录一下在哪出问题. 然后判断是否只有一个裁判没有出现问题.如果只有一个,说明可以确定,那么就是剩下的人出问题的最大值.因为只有否定了其它所有人,才能