并查集练习1:HDOJ1213

来源:互联网 发布:p2p网络正在连接 编辑:程序博客网 时间:2024/05/22 03:23

基础的并查集练习,可以水过。

quick find :

直接循环改数,时间复杂度为N方。

#include <iostream>using namespace std;int id[1005] ;void unionroot(int a, int b, int N );int main(){    int T=0 ;    cin >> T ;    while(T--)    {        int N = 0,M = 0, num = 0;        int a , b ;        cin >> N >> M ;        for(int i=1 ; i<=N ; i++)            id[i] = i;        while(M--)        {            cin >> a >> b ;            unionroot(a, b, N);        }        for(int i=1 ; i<=N ; i++)            if(i==id[i])                num++;        cout << num << endl ;    }    return 0;}void unionroot(int a, int b, int N ){    int idp = id[a] ;    int idq = id[b] ;    for(int i = 1 ; i <= N ; i++)        if(id[i]==idp)        id[i] = idq ;}


quick union:存储父亲节点名字,find的时候看根节点是否相同,union的时候根节点相连。时间复杂度依然很高,因为可能有树太深。

#include <iostream>using namespace std;int id[1005] ;void unionroot(int a, int b, int N );int findroot(int a);int main(){    int T=0 ;    cin >> T ;    while(T--)    {        int N = 0,M = 0, num = 0;        int a , b ;        cin >> N >> M ;        for(int i=1 ; i<=N ; i++)            id[i] = i;        while(M--)        {            cin >> a >> b ;            unionroot(a, b, N);        }        for(int i=1 ; i<=N ; i++)            if(i==id[i])                num++;        cout << num << endl ;    }    return 0;}void unionroot(int a, int b, int N ){    int idp = findroot(a) ;    int idq = findroot(b) ;    id[idp] = idq ;}int findroot(int a){    while(a!=id[a])    {        a = id[a] ;    }    return a ;}


weighted quick union :

#include <iostream>#include <string.h>using namespace std;int id[1005] ;int weight[1005] ;void unionroot(int a, int b, int N );int findroot(int a);int main(){    int T=0 ;    cin >> T ;    while(T--)    {        int N = 0,M = 0, num = 0;        int a , b ;        cin >> N >> M ;        memset(weight, 1, sizeof(int));        for(int i=1 ; i<=N ; i++)            id[i] = i;        while(M--)        {            cin >> a >> b ;            unionroot(a, b, N);        }        for(int i=1 ; i<=N ; i++)            if(i==id[i])                num++;        cout << num << endl ;    }    return 0;}void unionroot(int a, int b, int N ){    int idp = findroot(a) ;    int idq = findroot(b) ;    if(weight[idq] <= weight[idp])    {        id[idp] = idq ;        weight[idq] += weight[idp] ;    }    else    {        id[idq] = idp ;        weight[idp] += weight[idq] ;    }}int findroot(int a){    while(a!=id[a])    {        a = id[a] ;    }    return a ;}


path compression:只在寻找根节点的同时加了一句提升根节点。

#include <iostream>#include <string.h>using namespace std;int id[1005] ;int weight[1005] ;void unionroot(int a, int b, int N );int findroot(int a);int main(){    int T=0 ;    cin >> T ;    while(T--)    {        int N = 0,M = 0, num = 0;        int a , b ;        cin >> N >> M ;        memset(weight, 1, sizeof(int));        for(int i=1 ; i<=N ; i++)            id[i] = i;        while(M--)        {            cin >> a >> b ;            unionroot(a, b, N);        }        for(int i=1 ; i<=N ; i++)            if(i==id[i])                num++;        cout << num << endl ;    }    return 0;}void unionroot(int a, int b, int N ){    int idp = findroot(a) ;    int idq = findroot(b) ;    if(weight[idq] <= weight[idp])    {        id[idp] = idq ;        weight[idq] += weight[idp] ;    }    else    {        id[idq] = idp ;        weight[idp] += weight[idq] ;    }}int findroot(int a){    while(a!=id[a])    {        id[a] = id[id[a]];        a = id[a] ;    }    return a ;}



0 0
原创粉丝点击