• 【Baltic2003】【BZOJ1370】Gang团伙(并查集,拆点)


    problem

    • 给定n个人
    • 朋友的朋友是朋友,敌人的敌人是朋友
    • 朋友之间组成一个团伙,求团伙数

    solution

    • 将每个点x拆成两个:x和x+n(分别表示x的朋友和敌人)
    • 如果x和y是朋友,就将x和y合并
    • 如果x和y是敌人,就将x和y+n合并,将y和x+n合并
    • 注意朋友的敌人不一定是敌人,因此如果x和y是朋友,不能将x+n和y+n合并

    codes

    #include<iostream>
    #include<algorithm>
    #define maxn 1010
    using namespace std;
    
    //UnionFindSet
    int fa[maxn<<1];
    void init(int n){for(int i = 1; i <= n; i++)fa[i]=i;}
    int find(int x){return x==fa[x]?x:fa[x]=find(fa[x]);}
    void merge(int x, int y){x=find(x);y=find(y);if(x==y)return;fa[x]=y;}
    
    int main(){
        int n, m;
        cin>>n>>m;
        init(maxn<<1);
        for(int i = 1; i <= m; i++){
            char op;  int x, y;
            cin>>op>>x>>y;
            if(op=='F'){
                merge(x,y);
                //merge(x+n,y+n);
            }else{
                merge(x,y+n);
                merge(x+n,y);
            }
        }
        int a[maxn];
        for(int i = 1; i <= n; i++)
            a[i]=find(i);
        sort(a+1,a+n+1);
        int ans = 0;
        for(int i = 1; i <= n; i++)
            if(i==1 || a[i]!=a[i-1])
                ans++;
        cout<<ans<<'
    ';
        return 0;
    }
  • 相关阅读:
    [HDU] 2084 数塔 入门dp
    一些实用的小技术,不定时更新^_^
    上传图片的综合验证
    一个典型web接口处理
    js控制背景音乐播放
    心开始平和起来
    冲突域广播域
    可怜的我的啊~~
    祈祷
    昨夜小楼又东风...
  • 原文地址:https://www.cnblogs.com/gwj1314/p/9444754.html
Copyright © 2020-2023  润新知