{1},{2,4,6},{3,5}
朋友的朋友是我的朋友很好解决,直接并掉两个集合
关键是敌人的敌人就是我的朋友。
这个条件用拆点来解决
假设$x,y$敌对,将$x$和$y+n$这两个集合还有$y$,$x+n$这两个集合并起来就可以了
为什么要这样呢?
假设$a,b$为敌,$b,c$为敌,这样就可以把$a,c$并起来了
另外要注意细节,比如初始化$f[i]$要$for$到$2n$,跑完$m$个关系后要再重新跑一遍
#include <bits/stdc++.h> using namespace std ; #define N 5000 int n , m ; int f[ N ] , a[ N ] ; int find( int x ) { if( f[ x ] == x ) { return x ; }return f[ x ] = find( f[ x ] ) ; } int main() { scanf( "%d%d" , &n , &m ) ; for( int i = 1 ; i <= 2 * n ; i ++ ) f[ i ] = i ; for( int i = 1 ; i <= m ; i ++ ) { char ch[ 10 ] ; int x , y ; scanf( "%s%d%d" , ch , &x , &y ) ; if( ch[ 0 ] == ‘F‘ ) f[ find( y ) ] = find( x ) ; else { f[ find( y + n ) ] = find( x ) ; f[ find( x + n ) ] = find( y ) ; } } int ans = 0 ; for( int i = 1 ; i <= n ; i ++ ) f[ i ] = find( i ) ; sort( f + 1 , f + n + 1 ) ; for( int i = 1 ; i <= n ; i ++ ) { if( f[ i ] != f[ i - 1 ] ) ans ++ ; } printf( "%d\n" , ans ) ; }
[BZOJ1370][Baltic2003]Gang团伙 并查集+拆点
原文:https://www.cnblogs.com/henry-1202/p/BZOJ1370.html