|Tyvj|并查集|P1602 团伙

来源:互联网 发布:战舰世界排位赛数据 编辑:程序博客网 时间:2024/06/05 16:50

http://tyvj.cn/p/1602

方法一:拆点

#include<cstdio>#include<algorithm>#include<cstring>#include<queue>#define ms(i,j) memset(i,j, sizeof i);using namespace std; int n,m; int father[2005];int find(int x){if (father[x]==x) return x;return father[x] = find(father[x]);}int merge(int x, int y){int x1 = find(x);int y1 = find(y);if (x1!=y1) father[y1] = x1;}int main(){scanf("%d%d", &n, &m);for (int i=1;i<=2*n;i++) father[i] = i;for (int i=1;i<=m;i++){char ch[10];int p,q;scanf("%s %d %d", ch, &p, &q);char c = ch[0];if (c=='F'){merge(p,q);} else{merge(p, q+n);merge(q, p+n);}}int ans = 0;for (int i=1;i<=2*n;i++) find(i);for (int i=1;i<=n;i++)if (father[i]==i) ans++;printf("%d\n", ans);    return 0;}


方法二:输入如果是朋友就合并,是敌人就邻接表储存起来,然后输入完之后合并所有的敌人,最后统计代表个数即可

#include<cstdio>#include<cstring>#include<algorithm>using namespace std;int num[1005], f[1005][1005];int father[1005];int n,m;int find(int i){if (father[i]!=i) father[i] = find(father[i]);return father[i];}int merge(int x, int y){int r1 = find(x);int r2 = find(y);father[r2] = r1;}int main () { scanf("%d%d%*c", &n, &m);for (int i=1;i<=n;i++) father[i] = i;memset(num, 0, sizeof(num));for (int i=1;i<=m;i++){char c;int p,q;c = getchar();scanf("%d%d%*c", &p, &q);if (c=='F'){merge(p, q);} else {f[p][++num[p]] = q;f[q][++num[q]] = p;}}for (int k=1;k<=n;k++){for (int i=1;i<=num[k];i++)for (int j=1;j<=num[k];j++){merge(f[k][i], f[k][j]);}}for (int i=1;i<=n;i++) find(i);int ans = 0;for (int i=1;i<=n;i++){if (father[i]==i) ans++;}printf("%d\n", ans);return 0;}


0 0