zoukankan      html  css  js  c++  java
  • 【bzoj1370】[Baltic2003]Gang团伙 并查集

    题目描述

    在某城市里住着n个人,任何两个认识的人不是朋友就是敌人,而且满足: 1、 我朋友的朋友是我的朋友; 2、 我敌人的敌人是我的朋友; 所有是朋友的人组成一个团伙。告诉你关于这n个人的m条信息,即某两个人是朋友,或者某两个人是敌人,请你编写一个程序,计算出这个城市最多可能有多少个团伙?

    输入

    第1行为n和m,N小于1000,M小于5000; 以下m行,每行为p x y,p的值为0或1,p为0时,表示x和y是朋友,p为1时,表示x和y是敌人。

    输出

    一个整数,表示这n个人最多可能有几个团伙。

    样例输入

    6
    4
    E 1 4
    F 3 5
    F 4 6
    E 1 2

    样例输出

    3


    题解

    并查集

    输入描述有误,以下m行第一个是字母,F表示friend,E表示enemy。

    如果x、y是朋友,则合并x和y;

    如果x、y是敌人,则合并x、y+n和x+n、y。

    这样能保证敌人的敌人是朋友,满足题中条件。

    然后统计有多少个f[i]就可以。

    #include <cstdio>
    int f[2010] , vis[2010];
    char str[5];
    int find(int x)
    {
        return x == f[x] ? x : f[x] = find(f[x]);
    }
    void merge(int x , int y)
    {
        int tx = find(x) , ty = find(y);
        f[tx] = ty;
    }
    int main()
    {
        int n , m , i , x , y , ans = 0;
        scanf("%d%d" , &n , &m);
        for(i = 1 ; i <= 2 * n ; i ++ )
            f[i] = i;
        while(m -- )
        {
            scanf("%s%d%d" , str , &x , &y);
            if(str[0] == 'F')
                merge(x , y);
            else
                merge(x , y + n) , merge(x + n , y);
        }
        for(i = 1 ; i <= n ; i ++ )
            if(!vis[find(i)])
                vis[f[i]] = 1 , ans ++ ;
        printf("%d
    " , ans);
        return 0;
    }
  • 相关阅读:
    读书笔记-8《构建之法》
    结对编程收获
    结对编程——四则运算器(UI第十组)
    读书笔记-7《构建之法》
    读书笔记-6《构建之法》
    【现代软件工程】个人总结
    【现代软件工程】6月中旬团队项目心得
    【读书笔记】——《代码大全》(六)
    【现代软件工程】五月团队项目心得
    【读书笔记】——《代码大全》(五)
  • 原文地址:https://www.cnblogs.com/GXZlegend/p/6405309.html
Copyright © 2011-2022 走看看