有情人终成兄妹
相信这样的狗血剧情韩剧里有很多。

这种情况往往只会出现在特别特别大的家庭里,而且家庭成员分布各地。但人一般都不会看族谱,所以在根本不知道对方是自己妹妹的情况下与之相爱。

将其变成

那我们马上就可以知道我们祖先是谁,碰到妹子可以直接问她祖先是谁就可以防止上面的尴尬了。

不好意思以上纯属本人玩笑。
好的正经点,古时江湖两人决斗后发现是同门人岂不是很尴尬,但是一级一级上去问又太麻烦了,假如每个成员的直接上级都变成堂主,在决斗之前先问问对方自己的堂主是谁,不就可以避免自相残杀让别的门派看笑话了吗?正好并查集可以实现每个人上一级直接就是堂主。
首先呢要实现每个成员的直接上级就是堂主,哪就先得知道堂主是谁(也就相当于一棵树的根);
接下来我用代码展示
1.找到堂主
2.将 从此成员一直到堂主 这条路径上每个成员的直接上级变成堂主。
代码如下:
int find_boss(int boss)
{
// 此处为 1 号操作
int dd = boss, t;
while(root != member[boss])// member数组元素代表每个成员直接上级,例如member[i]代表i的直接上级
boss = member[boss];// 当某个成员直接上级为自己时,说明他就是堂主!!!
// 此处为 2 号操作
while(dd != boss)// 此时 boss已经是真正的boss(堂主)了!!!
{
t = member[dd];
member[dd] = boss;
dd = t;
}
return boss;
}
但最开始是没有门派的,也可以说每个人就是一派;所以 member 数组初始化如下:
for(i = 1; i <= n; i++)
member[i] = i;
1.假如后来堂主都想着合并帮派,每个门派都会安排人(人数不定)出去
2.遇到人就先问他属于哪个门派
3.假如不属于同一门派,则双方上报堂主
4.双方门派堂主通过决斗,赢家合并对方门派,成为新门派堂主
5.求最终门派数量
代码如下:
int person1, person2;
scanf("%d%d",&person1,&person2);// 此为相遇的两人
person1 = find_boss(person1);
person2 = find_boss(person2);
if(person1 != person2)// 堂主不为统一位,则堂主双方堂主决斗
member[person1] = person2;// 我们这里固定赢家为 2 方
// 因为最终都是变成一个门派
最终统计剩余门派:
1.我们先要把每个江湖人物的堂主找出
2.再判断堂主是否为自己,一个堂主即为一个门派
代码如下:
int ans = 0;
for(i = 1; i <= n; i++)
member[i] = find_boss(i);
// 找出每个江湖人物的堂主
for(i = 1; i <= n; i++)
if(i==member[i]) ans++;
最终代码如下:
#include<stdio.h>
int member[10000100]={0};
int find_boss(int boss)
{
int dd = boss, t;
while(boss != member[boss])
boss = friend[boss];
while(dd != boss)
{
t = member[dd];
member[dd] = boss;
dd = t;
}
return boss;
}
int main()
{
int n,m;
while(scanf("%d%d",&n,&m)!=EOF)
{
int i;
for(i = 1; i <= n; i++)
member[i] = i;
while(m--)
{
int person1, person2;
scanf("%d%d",&person1,&person2);
person1 = find_boss(person1);
person2 = find_boss(person2);
if(person1 != person2)
member[person1] = person2;
}
for(i = 1; i <= n; i++)
member[i] = find_boss(i);
for(i = 1; i <= n; i++)
if(i==member[i])ans++;
printf("%d\n",ans);
}
return 0;
}
谢谢!!!
本文介绍了一种使用并查集数据结构管理江湖门派的技术。通过将成员的直接上级设定为堂主,可以高效地进行门派合并,避免自相残杀,最终统计门派数量。
1182





