输入两个数字的组合表示这两个人同信仰,问最后又多少种信仰
太明显的并查集,没什么好说的了,只是这题压缩路径会效率很差,因为并的操作是大多,不压缩路径对于并操作来说更快
压缩路径后并的操作要遍历数组,效率就低多了
初始时设信仰数为总人数,每一次并的操作信仰数减一,就能得到最后信仰总数。
压缩路径3657MS,不压缩282MS
不压缩路径算法:
#include <stdio.h> int student[50001],n=0; int count; inline int find(int x) { while(student[x]!=x) { x=student[x]; } return x; } void change(int x,int y) { int i=0; int px=find(x),py=find(y); if(px!=py) { --count; student[px]=py; } return; } int main(void) { int k=0,m=0; int i=0,x=0,y=0; while(scanf("%d%d",&n,&m)&&n+m) { for(i=1;i<=n;++i) { student[i]=i; } count=n; for(i=0;i<m;++i) { scanf("%d%d",&x,&y); change(x,y); } printf("Case %d: %d\n",++k,count); } }
压缩路径算法:
#include <stdio.h>
int student[50001],n=0;
int count;
void change(int x,int y)
{
int i=0,temp=0;
if(student[x]!=student[y])
{
--count;
temp=student[y];
for(i=1;i<=n;++i)
{
if(student[i]==temp)
{
student[i]=student[x];
}
}
}
}
int main(void)
{
int k=0,m=0;
int i=0,x=0,y=0;
while(scanf("%d%d",&n,&m)&&n+m)
{
for(i=1;i<=n;++i)
{
student[i]=i;
}
count=n;
for(i=0;i<m;++i)
{
scanf("%d%d",&x,&y);
change(x,y);
}
printf("Case %d: %d\n",++k,count);
}
}