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條資訊,即某兩個人是朋友,或者某兩個人是敵人,請你編寫乙個程式,計算出這個城市最多可能有...