zoukankan      html  css  js  c++  java
  • 团伙(并查集)

    在某城市里住着n个人,任何两个认识的人不是朋友就是敌人,而且满足:
    1、我朋友的朋友是我的朋友;
    2、我敌人的敌人是我的朋友;
    所有是朋友的人组成一个团伙。告诉你关于这n个人的m条信息,即某两个人是朋友,或者某两个人是敌人,请你编写一个程序,计算出这个城市最多可能有多少个团伙?
    输入
    第1行为n和m; 以下m行,每行为p x y,p的值为0或1,p为0时,表示x和y是朋友,p为1时,表示x和y是敌人
    输出
    一个整数,表示这n个人最多可能有几个团伙。
    样例输入
    6 4
    1 1 4
    0 3 5
    0 4 6
    1 1 2
    样例输出
    3

    开始还真没看出来

    因为一个人的敌人的敌人是自己的朋友

    那我们就直接在用一个数组记录每个人的敌人

    这样每次我们合并一对敌人的时候

    就分别把另一个人的敌人给合并了

    #include<bits/stdc++.h>
    using namespace std;
    inline int read(){
        char ch=getchar();
        int res=0;
        while(!isdigit(ch))ch=getchar();
        while(isdigit(ch)) res=(res<<3)+(res<<1)+(ch^48),ch=getchar();
        return res;
    }
    int e[10005],fa[10005],a[10005],n,m,ans;
    inline int find(int x){
        if(fa[x]!=x) fa[x]=find(fa[x]);
        return fa[x];
    }
    inline void merge(int x,int y){
        int f1=find(x),f2=find(y);
        if(f1!=f2) fa[f1]=f2;
    }
    inline void merg(int u,int v){
        if(!e[u]) e[u]=v;
        else{
            merge(v,e[u]);
        }
    }
    int main(){
        n=read();m=read();
        for(int i=1;i<=n;i++)fa[i]=i;
        for(int i=1;i<=m;i++){
            int op=read(),u=read(),v=read();
            if(op==0){
                merge(u,v);
            }
            else{
                merg(u,v);
                merg(v,u);
            }
        }
        for(int i=1;i<=n;i++)
        {
            a[i]=find(i);
        }
        sort(a+1,a+n+1);
        for(int i=1;i<=n;i++){
            if(a[i]!=a[i-1]) ans++;
        }
        cout<<ans<<endl;
        return 0;
    }
    
  • 相关阅读:
    自定义TypeConverter把基础类型转换为复杂类型
    自学MVC看这里——全网最全ASP.NET MVC 教程汇总
    C#枚举器接口IEnumerator的实现
    nopCommerce架构分析系列(二)数据Cache
    NET下三种缓存机制(Winform里面的缓存使用 )
    【RequireJS--API学习笔记】
    Linux文件的所有权与权限
    ftp服务及其实现之vsftpd
    计算机传输层端口分类
    命令:tr
  • 原文地址:https://www.cnblogs.com/stargazer-cyk/p/10366479.html
Copyright © 2011-2022 走看看