洛谷 P1892 [BOI2003] 团伙 种类并查集 扩展域并查集

P1892 [BOI2003] 团伙

种类并查集!!!!

存敌人

主要要理解敌人的敌人就是朋友这句话,我们就可以用并查集来维护朋友,用一个数组来储存他的其中一个敌人,后面遇到其他他的敌人时,将他的敌人用并查集连起来成为朋友。

注意这题要你输出团队数而不是团队的人数不会就我这么唐吧

#include <bits/stdc++.h>
using namespace std;
const int N=1005;
int n,m;
int fa[N];
int a[N];
int find(int x){
return fa[x]==x?x:find(fa[x]);
}
void add(int u,int v){
int x=find(u);
int y=find(v);
fa[x]=y;
}
int cnt[1005];
int ans;
int main(){
ios::sync_with_stdio(false);
cin>>n>>m;
for(int i=1;i<=n;i++){
fa[i]=i;
}
for(int i=1;i<=m;i++){
char c;
int u,v;
cin>>c>>u>>v;
if(c=='F'){
add(u,v);
}
else{
if(!a[u]){
a[u]=v;
}
else{
add(a[u],v);
}
if(!a[v]){
a[v]=u;
}
else{
add(a[v],u);
}
}
}
for(int i=1;i<=n;i++){
if(fa[i]==i){
ans++;
}
}
cout<<ans;
return 0;
}

反集

当然这题的方法开两倍空间进行维护,或者说叫反集。

#include <bits/stdc++.h>
using namespace std;
const int N=2005;
int n,m;
int fa[N];
int find(int x){
return fa[x]==x?x:find(fa[x]);
}
void add(int u,int v){
int x=find(u);
int y=find(v);
fa[x]=y;
}
int ans;
int main(){
ios::sync_with_stdio(false);
cin>>n>>m;
for(int i=1;i<=n*2;i++){
fa[i]=i;
}
for(int i=1;i<=m;i++){
char c;
int u,v;
cin>>c>>u>>v;
if(c=='F'){
add(u,v);
}
else{
add(u+n,v);
add(v+n,u);
}
}
for(int i=1;i<=n;i++){
if(fa[i]==i){
ans++;
}
}
cout<<ans;
return 0;
}
posted @   sad_lin  阅读(8)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· .NET10 - 预览版1新功能体验(一)
点击右上角即可分享
微信分享提示