并查集算法是用于查找/分辨 某单个与另某单个是否为同一个群体。
比如,可以通过询问N组的 A B 是否为同一社团,然后问xxxa与xxxb 是否在同一社团。
又或者,可以识别,A与B是朋友 B与C是敌人,那么A与C 因为是敌人的敌人是朋友,所以A与C也是朋友。
也可以在最小生成树的时候,判断2个顶点在不在同一棵树内。
算法模板比较简单。
#define MAXN 1001
int fa[MAXN];
int getFa( int x) {
return fa[x] == x ? x : fa[x] = getFa(fa[x]);
}
void merge( int a,int b){
int x = getFa(a);
int y = getFa(b);
if ( x != y ){
fa[x] = y;
}
}
bool isSame(int a,int b){
int x = getFa(a);
int y = getFa(b);
return x==y;
}
附poj 1182 ac代码
#include <iostream>
#include <cassert>
#include <vector>
#include <queue>
#include <string>
#include <cstring>
#include <cmath>
#include <climits>
#include <functional>
#include <list>
#include <cstdlib>
#include <set>
#include <stack>
#include <map>
#include <algorithm>
using namespace std;
#define FALEN 150015
#define FAHLEN 50005
int fa[FALEN];
int getFah(int a){
return fa[a] == a ? a : getFah(fa[a]);
}
int getFa(int a){
int f = getFah(a);
fa[a] =f;
return f;
}
void mergeSame(int a,int b){
int f_a = getFa(a);
int f_b = getFa(b);
if ( f_a != f_b){
fa[f_a] = f_b;
}
}
bool isSame(int a,int b){
int f_a = getFa(a);
int f_b = getFa(b);
return f_a == f_b;
}
int main(){
int ans = 0;
for( int i=0;i<FALEN;++i ){
fa[i] = i;
}
int N,K;
scanf("%d%d",&N,&K);
int D,X,Y;
for( int i=0;i<K; ++i ){
scanf("%d%d%d",&D,&X,&Y);
if ( X > N || Y > N || X < 0 || Y < 0 ){
++ans ;
}else{
if ( D == 1 ){
if ( isSame(X,Y+FAHLEN) || isSame(X,Y+2*FAHLEN) ){
ans ++;
}else{
mergeSame(X,Y);//链式
mergeSame(X+FAHLEN,Y+FAHLEN);
mergeSame(X+2*FAHLEN,Y+2*FAHLEN);
}
}else if ( D == 2 ){
if ( isSame(X,Y) || isSame(X,Y+2*FAHLEN)){
ans ++;
}else{
mergeSame(X,Y+FAHLEN);//链式
mergeSame(X+FAHLEN,Y+2*FAHLEN);
mergeSame(X+2*FAHLEN,Y);
}
}
}
}
cout << ans << endl;
return 0;
}