ybt 1385:团伙(group)
洛谷 P1892 [BOI2003]团伙
每个人是一个元素,一个团伙是一个集合。
也就是说一个人的所有敌人都互为朋友,同属于一个集合。
因此,设数组enemy, enemy[i]
表示i的某一个敌人。
当x与y互为敌人时,先考虑y作为x的敌人的情况:
enemy[x] == 0
),就将y设为x的一个敌人,即enemy[x]=y
enemy[x] > 0
),那么应该将y加入x的敌人组成的集合,即将y与enemy[x]
所在的集合合并。反过来,同时要考虑x作为y的敌人的情况:
enemy[y] == 0
),就将x设为y的一个敌人,即enemy[y]=x
enemy[y] > 0
),那么应该将x加入y的敌人组成的集合,即将x与enemy[y]
所在的集合合并。并查集中每个集合的根结点满足fa[i] == i
,集合的数量就是fa数组中根结点的个数。
最后输出集合的数量。
#include<bits/stdc++.h>
using namespace std;
#define N 1005
int n, m, fa[N], enemy[N];//fa[i]:i的双亲 enemy[i]:i的某个敌人
void init(int n)
{for(int i = 1; i <= n; ++i)fa[i] = i;
}
int find(int x)//查找x所在集合的根结点
{if(fa[x] == x)return x;return fa[x] = find(fa[x]);
}
void merge(int x, int y)//合并x,y所在的集合
{fa[find(x)] = find(y);
}
int main()
{char opt;int p, q, ct = 0;cin >> n >> m;init(n);for(int i = 1; i <= m; ++i){cin >> opt >> p >> q;if(opt == 'F')merge(p, q);else //opt = 'E' 敌人 {if(enemy[p])//如果p有敌人enemy[p] merge(enemy[p], q);//将q加入到p敌人组成的集合 else//如果p没有敌人 enemy[p] = q;//q作为p的敌人 if(enemy[q])merge(enemy[q], p);elseenemy[q] = p;}}for(int i = 1; i <= n; ++i)if(fa[i] == i)//i是根结点 ct++;cout << ct;return 0;
}
本文发布于:2024-02-01 11:30:57,感谢您对本站的认可!
本文链接:https://www.4u4v.net/it/170675825736290.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
留言与评论(共有 0 条评论) |