回复 6楼 lin5161678
不知道有没有bug,大概就是这样子~
PS:改了一点,大概就是这样子了
~
程序代码:
#include <stdio.h>
/*
数组元素
大于0 表示这个集合有多少个元素
小于0 表示这个元素属于哪个集合
*/
int arr[1000000];
//查找元素n的根节点
int find(int n)
{
while(arr[n] < 0)
n = -arr[n];
return n;
}
void merge( int n,int m )
{
while(arr[n] < 0)
{
int t=n;
n=-arr[n];
arr[t]=m;
}
}
int main(int argc, char *argv[])
{
int n, m;
while(scanf("%d%d", &n, &m) == 2)
{
//一开始全部初始化为1 表示 每一个集合都只有1个元素 就是这个元素本身
for(int i=1; i<n+1; ++i)
arr[i] = 1;
while(m--)
{
int x,y;
scanf("%d%d", &x, &y);
int rootx = find(x);
int rooty = find(y);
//如果元素x 和 元素y 的根节点不一样 就合并
if (rootx!=rooty)
{
//两个节点的元素个数加起来
arr[rootx] += arr[rooty];
//rooty作为rootx的根节点
arr[rooty] = -rootx;
}
merge(x,-rootx);
merge(y,-rootx);
}
int max = 0;
for(int i=0; i<n; ++i)
{
if(max < arr[i])
max = arr[i];
}
printf("\n%d\n", max);
}
return 0;
}
以下是引用lin5161678在2018-5-16 22:28:56的发言:
想错了
查找树2层 每次修改节点是不会超过3个 还是2个
的确是很优秀 我写写看
不一定是两层,总之这个可以看出是o(n),因为重复遍历一遍的结点都会变成根结点
~
[此贴子已经被作者于2018-5-18 05:42编辑过]