1. 程式人生 > >【洛谷P1892】團夥

【洛谷P1892】團夥

urn else unique 容易 const find its main 敵人

題目大意:維護 N 個人和 M 個關系,對每個人來說符合:我朋友的朋友也是我的朋友,我敵人的敵人也是我的朋友,求最多有多少個朋友構成的聯通塊。

題目大意:維護關系顯然要用到並查集,這裏是維護了兩種關系,即:朋友和敵人,應該有兩種做法,首先是維護帶權並查集,可用 0 表示兩人為朋友,1 表示兩人為敵人,不過這樣做似乎對於求有多少個朋友構成的聯通塊並不容易,因為只要兩個人有關系(無論什麽關系)都在一個聯通塊中;另一種做法就是擴展域並查集,將一個點拆成兩個點,分別表示自己朋友的集合和自己敵人的集合,這樣最後統計自己朋友的集合有多少聯通塊直接排序去重即可。

代碼如下

#include <bits/stdc++.h>
using namespace std;
const int maxn=1010;

int n,m,f[maxn<<1],a[maxn];
char opt[5];

int find(int x){
    return x==f[x]?x:f[x]=find(f[x]);
}

void read_and_parse(){
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n<<1;i++)f[i]=i;
}

void solve(){
    int x,y;
    while(m--){
        scanf("%s%d%d",&opt,&x,&y);
        if(opt[0]==‘F‘)f[find(x)]=find(y);
        else f[find(x)]=find(y+n),f[find(x+n)]=find(y);
    }
    for(int i=1;i<=n;i++)a[i]=find(i);
    sort(a+1,a+n+1);
    printf("%d\n",unique(a+1,a+n+1)-a-1);
}

int main(){
    read_and_parse();
    solve();
    return 0;
}

【洛谷P1892】團夥