pta 原题https://pta.patest.cn/pta/test/15/exam/4/question/840
并查集,看了比较好懂点击打开链接
有一点我没有注意到的是,在这个题目当中,按题输入的时候才会寻找某些结点的根节点并更新,所以pre数组中每个结点对应的可能并不一定其根节点也可能是父亲结点,也就是说路径压缩这个过程其实是滞后的,那么在计算人数的时候,就不能按照pre数组,而是要寻找其根节点。
源代码
#include<stdio.h>
int pre[30005]={0},cnt[30005]={0};
void creat(int n); //初始化每个结点的前导节点
int find(int x); //找到某个结点的根节点
void join(int x,int y); //判断两个结点是否联通,否则合并
int main()
{
int n,m,i,j,a,b,c,t,max = -1;
scanf("%d%d",&n,&m);
creat(n);
for(i=0;i<m;i++)
{
scanf("%d%d",&a,&b);
for(j=1;j<a;j++)
{
scanf("%d",&c);
join(b,c);
}
}
for(i=1;i<=n;i++)
{
t = find(i); //计算人数
cnt[t]++;
}
for(i=1;i<=n;i++)
{
if(pre[i]==i&&max<cnt[i])
max = cnt[i];
}
printf("%d\n",max);
return 0;
}
void creat(int n)
{
int i;
for(i=1;i<=n;i++)
pre[i] = i;
}
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)
{
int fx = find(x),fy = find(y);
if(fx!=fy)
{
pre[fy] = fx;
}
}