團夥 並查集 並查集 團夥

2021-10-13 10:53:21 字數 1519 閱讀 8736

2<=n<=1000

1<=m<=5000

1<=p q<=n

試題分析:這種問題我們一般有兩種解法:①打標記   ②多個並查集

打標記這類方法會在銀河英雄傳說中看到

那麼多個並查集如何解決呢?我們設1~n節點是記錄朋友,n+1~2*n節點是記錄敵人

既然兩個人是朋友,根據題意,我們也要把他們的敵人合起來

如果兩個人是敵人,那麼merge(a,b+n),merge(a+n,b)

如何查詢有幾個團夥呢,就把所有人的根節點放進乙個陣列裡面sort一下最後求下多少不同的就好了

**:#include

#include

#include

#include

#include

#include

#include

//#include

using namespace std;

const int inf = 9999999;

#define ll long long

inline int read(){

int x=0,f=1;char c=getchar();

for(;!isdigit(c);c=getchar()) if(c=='-') f=-1;

for(;isdigit(c);c=getchar()) x=x*10+c-'0';

return x*f;

int fa[3001];

int a[3001];

int n,m;

int ans;

void init(){

for(int i=1;i<=2*n;i++) fa[i]=i;

int find(int x){

if(x!=fa[x]) return fa[x]=find(fa[x]);

return x;

void merge(int a,int b){

int x=find(a),y=find(b);

if(x==y) return ;

fa[y]=x;

return ;

int main(){

//freopen(".in","r",stdin);

//freopen(".out","w",stdout);

n=read(),m=read();

init();

for(int i=1;i<=m;i++){

char c;cin>>c;

int a=read(),b=read();

if(c=='f'){

merge(a,b);

else{

merge(a+n,b);

merge(a,b+n);

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++;

printf("%d\n",ans);

return 0;

團夥 並查集 團夥 並查集

題目描述 1920年的芝加哥,出現了一群強盜。如果兩個強盜遇上了,那麼他們要麼是朋友,要麼是敵人。而且有一點是肯定的,就是 我朋友的朋友是我的朋友 我敵人的敵人也是我的朋友。兩個強盜是同一團夥的條件是當且僅當他們是朋友。現在給你一些關於強盜們的資訊,問你最多有多少個強盜團夥。輸入輸出格式 輸入格式 ...

並查集 團夥

題號 zhoj1258 思路 並查集。給每個人建立乙個 正集 朋友 乙個 反集 敵人 反集要麼為空 要麼指向乙個正集,維護這兩類集合,最後統計 正集 的個數。1 include2 include3 const int n 1000 4 intans 5class unionfindset 14 15...

團夥 並查集

problem description 在某城市裡住著n個人,任何兩個認識的人不是朋友就是敵人,而且滿足 1 我朋友的朋友是我的朋友 2 我敵人的敵人是我的朋友。所有是朋友的人組成乙個團夥。告訴你關於這n個人的m條資訊,即某兩個人是朋友,或者某兩個人是敵人,請你編寫乙個程式,計算出這個城市最多可能有...