• 【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;
    }
  • 相关阅读:
    相对定位和绝对定位
    Html中常见的块级元素
    浮动的用法
    c#中质数判断
    函数
    asp.net Jquery+json 实现无刷新分页
    MS CRM2011 某个用户(团队)对某个实体的操作权限
    asp.net sitemap url动态参数
    MS CRM 2011 更改团队的业务部门
    MS CRM 2011 解决记录总数问题
  • 原文地址:https://www.cnblogs.com/GXZlegend/p/6405309.html
Copyright © 2020-2023  润新知