https://qduoj.com/problem/95/
kkun的膜神帮
发布时间: 2016年7月2日 20:30 最后更新: 2016年7月2日 20:33 时间限制: 1000ms 内存限制: 128M
强大的kkun神当然会有一大群膜拜他的粉丝,但是这些粉丝确喜欢kkun的不同部分,例如他帅气的脸庞,比光还快的手速,无敌的智慧
等等。
于是这群粉丝就依据他们喜欢的部分组成各种膜kkun帮,kkun现在知道m对粉丝是一个帮派的,现在kkun想知道到底他的粉丝中有多少
帮派。
默认情况下,每个粉丝都是一个帮派,即初始有n个帮派,经过m行的输入后,输出帮派的数目。(粉丝编号由1开始),每个粉丝只会喜欢
kkun的一个部分
多组测试数据,每组数据第一行会输入两个数字n, m, 1 <= n, m <= 10^5,之后会有m行输入,每行有两个数字表示粉丝的编号,表示
这两个粉丝是一个帮派的,输入数据有可能重复。
输出帮派的数目
复制
10 6 1 2 1 2 1 3 2 3 2 5 9 10
#include<iostream>
#include<cstdio>
#include<cstring>
#include<map>
#include<set>
#include<algorithm>
#include<queue>
using namespace std;
const int maxn = 100005;
int pre[maxn];
int Find(int x)
{
int r = x;
while(pre[r] != r) r = pre[r];
int i = x, j;
while(pre[i] != r)
{
j = pre[i];
pre[i] = r;
i = j;
}
return r;
}
void join(int x, int y)
{
if(Find(x) != Find(y))
pre[Find(y)] = Find(x);//靠左原则
}
int main(void)
{
int n, m;
while(~scanf("%d%d", &n, &m))
{
for(int i = 1; i <= n; i++) pre[i] = i;
for(int i = 1; i <= m; i++)
{
int x, y;
scanf("%d%d", &x, &y);
join(x, y);
}
int sum = 0;
for(int i = 1; i <= n; i++)
{
if(pre[i] == i) sum++;
}
printf("%d\n", sum);
}
return 0;
}
发现自己可以改改并查集写法了, 这样写有点麻烦了,可以写的简单点,
代码:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<map>
#include<set>
#include<algorithm>
#include<queue>
using namespace std;
const int maxn = 100005;
int pre[maxn];
int Find(int x)
{
if(pre[x] == x) return x;
else return pre[x] = Find(pre[x]);
}
void join(int x, int y)
{
pre[Find(y)] = pre[Find(x)];//靠左原则
}
int main(void)
{
int n, m;
while(~scanf("%d%d", &n, &m))
{
for(int i = 1; i <= n; i++) pre[i] = i;
for(int i = 1; i <= m; i++)
{
int x, y;
scanf("%d%d", &x, &y);
join(x, y);
}
int sum = 0;
for(int i = 1; i <= n; i++)
if(pre[i] == i) sum++;
printf("%d\n", sum);
}
return 0;
}