zoukankan      html  css  js  c++  java
  • 团伙

    题目描述
    在某城市里住着n 个人,任何两个认识的人不是朋友就是敌人,而且满足:
    1、一个人的朋友的朋友是他的朋友。
    2、一个人敌人的敌人是他的朋友。
    3、一个人和他所有的朋友在同一个团伙。
    4、一个人的所有敌人是同一个团伙。
    告诉你关于这n 个人的m 条信息(即某两人是朋友,或者某两个人是敌人),请你计算出这个城市的人最多有多少个团伙。


    输入
    第一行:n(2<=n<=1000),m(1<=m<=5000),中间一个空格隔开。
    以下共m 行,每行的格式是:d x y,三个数中间一空格隔开,d=0:x 和y 是朋友,d=1:x和y 是敌人。


    输出
    N 个人最多组成了多少个团伙。


    样例输入
    6 4
    1 1 4
    0 3 5
    0 4 6
    1 1 2


    样例输出
    3


    提示
    5
    说明:{1}, {2, 4, 6}, {3, 5}共3 个团伙

    从题中的描述就可以判断出这是一道并查集题。

    首先,对于两人是朋友,就合并所在集合。对于两个人是敌人,比如a是b的敌人,那么就应该合并a和b的敌人所在的集合。同理,也要合并b和a的敌人所在的集合。

    那么可以开一个数组en[],en[i] = j 表示 i 的敌人是 j。那么若 i 和 j 是敌人,就应该合并 i 和en[j] 以及 j 和 en[i]。

    另一种表示敌人的方法是 i + n。就是合并 i 和 j + n 以及 j 和 i + n。

    给出第一个方法的代码

     1 #include<cstdio>
     2 #include<iostream> 
     3 #include<cstring> 
     4 #include<cmath>
     5 #include<algorithm> 
     6 using namespace std;
     7 const int maxn = 1e4 + 5;
     8 int p[maxn], en[maxn];
     9 int n, m, ans = 0;
    10 void init()
    11 {
    12     for(int i = 0; i < maxn; ++i) {p[i] = i; en[i] = 0;}
    13 }
    14 int Find(int x)
    15 {
    16     return p[x] == x ? x : p[x] = Find(p[x]);
    17 }
    18 void merge(int x, int y)
    19 {
    20     int px = Find(x), py = Find(y);
    21     if(px == py) return;
    22     else {p[px] = py; return;}
    23 }
    24 int main()
    25 {
    26     freopen("group.in", "r", stdin);
    27     freopen("group.out", "w", stdout);
    28     init();
    29     scanf("%d%d", &n, &m);
    30     for(int i = 1; i <= m; ++i)
    31     {
    32         int d, a, b; scanf("%d%d%d", &d, &a, &b);
    33         if(!d) merge(a, b);
    34         else                        
    35         {
    36             if(!en[a]) en[a] = b;        //a还没有敌人,就将b作为a的敌人所在集合的代表元素 
    37             else merge(b, en[a]); 
    38             if(!en[b]) en[b] = a;
    39             else merge(a, en[b]);         
    40         }
    41     }
    42     for(int i = 1; i <= n; ++i) if(p[i] == i) ans++;
    43     printf("%d
    ", ans);
    44 }
  • 相关阅读:
    【POJ 1958】 Strange Towers of Hanoi
    【HNOI 2003】 激光炸弹
    【POJ 3263】 Tallest Cow
    【POJ 2689】 Prime Distance
    【POJ 2777】 Count Color
    【POJ 1995】 Raising Modulo Numbers
    【POJ 1845】 Sumdiv
    6月16日省中集训题解
    【TJOI 2018】数学计算
    【POJ 1275】 Cashier Employment
  • 原文地址:https://www.cnblogs.com/mrclr/p/8894054.html
Copyright © 2011-2022 走看看