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;
    }
    
  • 相关阅读:
    字符串初始化、查找字符+获取字符
    冒泡排序
    JAVA中值类型和引用类型的不同?
    二维数组初始化,属性,遍历,输出各元素总和。
    数组定义属性遍历循环,输出最大数
    for穷举,叠代练习
    HTML--Boby部分之<a>标签
    HTML--Boby内标签之多行文本及下拉框
    HTML--Boby部分Input之重置
    HTML--Boby部分Input之上传文件
  • 原文地址:https://www.cnblogs.com/stargazer-cyk/p/10366479.html
Copyright © 2011-2022 走看看