算法分类:
数据结构
算法原理:
通过find函数找出该节点的根节点,
通过UNION函数将两棵树合并。
加入rank[N]来记录每个节点的秩(即树的高度),并按秩进行合并,可避免合并时的最糟糕情况,(树形为一条直线)
通过路径压缩可以减少每次寻找根节点的次数。
算法时间复杂度:
最坏情况为O(mlogn)
一般为O(m)
代码实现:(HDU1232-畅通工程)
/* * HDU 1232 畅通工程 * 并查集 */ #include <iostream> using namespace std; const int SIZE = 1005; int root[SIZE]; int rank[SIZE]; int find(int x) { int y = x; while (root[y] != y) { y = root[y]; } int temp, head = y; y = x; while (root[y] != y) { temp = root[y]; root[y] = head; y = temp; } return head; }; void UNION(int x, int y) { int f1 = find(x); int f2 = find(y); if (rank[f1] <= rank[f2]) { root[f1] = f2; if (rank[f1] == rank[f2]) { rank[f2] ++; } } else { root[f2] = f1; } }; int main() { int N, M, s, e, count; while (scanf("%d%d",&N,&M)!=EOF, N) { for (int i = 1; i <= N; ++ i) root[i] = i; for (int i = 0; i < M; ++ i) { scanf("%d%d",&s,&e); UNION(s,e); } count = -1; for (int i = 1; i <= N; ++ i) { if (root[i] == i) ++ count; } printf("%d\n",count); } }