回复 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编辑过]