数据结构专题

来源:互联网 发布:玉溪餐饮软件yxqlkj 编辑:程序博客网 时间:2024/05/01 02:43
一.并查集
主要操作:


1.合并两个不相交集合


2.判断两个元素是否属于同一集合


时间复杂度:


O(n*α(n)),其中α(x),对于x=宇宙中原子数之和,α(x)不大于4,事实上,路经压缩后的并查集的复杂度是一个很小的常数。


模板题

#include <iostream>#include<stdio.h>using namespace std;//for poj 1611const int MAXN = 30001;int pa[MAXN],rank[MAXN],num[MAXN];void make_set(int x){    pa[x] = x;    rank[x] = 0;    num[x] = 1;}int find_set(int x){    int root = x, temp;    while(pa[root] != root) root = pa[root];    while(x != root){        temp = pa[x];        pa[x] = root;        x = temp;    }    return root;}void union_set(int x, int y){    x = find_set(x);    y = find_set(y);    if(x == y)return ;    if(rank[x] > rank[y]){/*让rank比较高的作为父结点*/        pa[y] = x;        num[x] += num[y];    }    else {        pa[x] = y;        if(rank[x] == rank[y])            rank[y]++;        num[y] += num[x];    }}int main(){    int n, m, x, y, i, t, j;    while(scanf("%d%d", &n, &m) && (m || n)){        if(m == 0){            cout << "1\n"; continue;        }        for(i = 0; i < n; i++)            make_set(i);        for(i = 0; i < m; i++){            scanf("%d", &t);            scanf("%d", &x);            for(j = 1; j < t; j++){                scanf("%d", &y);                union_set(x, y);                x = y;            }        }                /*找到0所在的树的树根*/        x = find_set(0);        cout << num[x] << endl;    }    return 0;}


原创粉丝点击