zoukankan      html  css  js  c++  java
  • openjudge T017 黑社会团伙 (并查集)

    1493: 黑社会团伙

    Time Limit: 1 Sec  Memory Limit: 128 MB

    Description

    众所周知,香港的黑社会组织猖獗,警方希望能摸清他们的内部构成情况,特派小生前往调查。经过长期的卧底,小生初步获得了一些资料:整个组织有n个人,任何两个认识的人不是朋友就是敌人,而且满足:


    我朋友的朋友是我的朋友;

    我敌人的敌人是我的朋友。

    所有是朋友的人组成一个团伙。现在,警方委派你协助调查,拥有关于这n个人的m条信息(即某两个人是朋友,或某两个人是敌人),请你计算出这个城市最多可能有多少个团伙。

    Input

    第一行包含一个整数N,第二行包含一个整数M,接下来M行描述M条信息,内容为以下两者之一:“F x y”表示xy是朋友;“E x y”表示xy是敌人(1≤x≤y≤N)。


    Output

    包含一个整数,即可能的最大团伙数。

    Sample Input

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

    Sample Output

    3

    HINT

    数据范围:2≤N≤2000,1≤M≤5000。

    这道题思路很清晰,是一个团伙的人都插在一个集合里,

    问题就在于我们如何判断两个人是不是一个团伙。

    当两人是朋友,很容易判断他们是一个团伙。

    当两个人是敌人,根据题意“敌人的敌人就是朋友”

    我们就要弄清如何判断敌人的敌人

    很多并查集里的题都用到一个思想,

    用一个步骤点,来将集合连接

    如果两个人是敌人那么连接,(x,y+n)和(y,x+n)

    这样我们可以创造出一个不存在的人,来做他的朋友

    当两个人的敌人相同时,他们的“不存在的朋友”就是相同的,就连接成了一个团伙了。

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    int set1[10001];
    int rank1[10001];
    int data[10001];
    int con[10001];
    bool cmp(int a,int b)
    {
        return a>b;
    }
    void Make_Set(int i)
    {
        set1[i]=i;
        rank1[i]=0;
    }
    int find1(int i)
    { 
        if(set1[i]==i)
        return set1[i];
        return find1(set1[i]);        
    }
    void Union(int i,int j)
    {
        i=find1(i);
        j=find1(j);
        if(i==j) 
        return;
        if(rank1[i]>rank1[j]) 
        set1[j]=i;
        else
        {
            if(rank1[i]==rank1[j]) 
            rank1[j]++;   
            set1[i]=j;
        }
    }
    int main()
    {
        int n,m,x,y;
        char a;
        int i,j;
        scanf("%d%d",&n,&m);    
        for(i=1;i<=n*2;i++)
        {
            Make_Set(i);
        }
        for(i=1;i<=m;i++)
        {
            cin>>a;
            scanf("%d%d",&x,&y);
            if(a=='F')
            Union(x,y);
            if(a=='E')
            {
                Union(x,y+n);
                Union(y,x+n);
            }
        }
        int step,ans=0;
        for(i=1;i<=n*2;i++)
        con[i]=find1(i);
        sort(con,con+n+1,cmp);
        for(i=1;i<=n;i++)
        {
            if(con[i]!=con[i-1])
            ans++;
        }
        printf("%d",ans);
         
    }
    View Code
  • 相关阅读:
    中国广电工信战争
    围观一个People Search
    Popular榜单能做到小众化吗?
    校园招聘:内地大学生的视野和实践有问题吗?
    锐推榜的平衡策略
    PyQt 自定义信号带参数 emit
    Python pyinstaller
    Python 匿名函数 lambda
    PyQT5 绑定函数的传参(connect 带参数)
    Excel 一列文本变为数字
  • 原文地址:https://www.cnblogs.com/ashon37w/p/7086825.html
Copyright © 2011-2022 走看看