题目
题意简述
若两人是朋友则合并两人所在的并查集,若两人是敌人则合并自己与对方所有敌人所在的并查集。
思路
建立一个二维数组来存储每两个人之间的关系,1
表示是敌人,0
表示是朋友。
code
#include <bits/stdc++.h>
using namespace std;
int dir[1010][1010],f[1010];
int find(int a){//查找负责人
if(f[a]==a) return a;
return f[a]=find(f[a]);
}
void jr(int a,int b){//合并操作
int t1=find(a),t2=find(b);
if(t1!=t2) f[t1]=t2;
}
int main(){
int n,m,x,y;
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++) f[i]=i;
char opt;
for(int j=0;j<m;j++){
scanf(" %c%d%d",&opt,&x,&y);
if(opt=='F') jr(x,y);
else if(opt=='E'){
dir[x][y]=1;
dir[y][x]=1;
for(int i=1;i<=n;i++){
if(dir[x][i]) jr(y,i);
if(dir[i][y]) jr(i,x);
}
}
}
int tot=0;
for(int i=1;i<=n;i++){
if(f[i]==i) tot++;
}
printf("%d",tot);
return 0;
}
分析
for(int j=0;j<m;j++){
scanf(" %c%d%d",&opt,&x,&y);
if(opt=='F') jr(x,y);//合并
else if(opt=='E'){
dir[x][y]=1;
dir[y][x]=1;
for(int i=1;i<=n;i++){
if(dir[x][i]) jr(y,i);//枚举 x所有的敌人,与 y合并
if(dir[i][y]) jr(i,x);//枚举 y所有的敌人,与 x合并
}
}
}
if(f[i]==i) tot++;
依据:每个并查集都只有一个根,所以访问到负责人答案就可以++