Union Find 并查集

来源:互联网 发布:surfacepro4 续航优化 编辑:程序博客网 时间:2024/05/22 18:03

Dynamic connectivity:

Union Command: connect two objects

Find query: is there a path connecting the two objects?


Quick Find:

用一个数组来表示所有connected component。每个数字顶点在数组中都有一个set index。如果两个顶点的set index是一样的,则表示它们是连接的。

容易find,但union复杂。union(a,b) 将a所在的connected component的set index改成b的set index。

public class QuickFind {private int[] id;public QuickFind(int N) {id = new int[N];// Initializationfor (int i = 0; i < N; i++) {id[i] = i;}}// O(1) accesspublic boolean connected(int p, int q) {return id[p] == id[q];}// O(N) accesspublic void union(int p, int q) {int pid = id[p];int qid = id[q];for (int i = 0; i < id.length; i++) {if (id[i] == pid) {id[i] = qid;}}}}

Quick Union:

树形结构,每个数字顶点都有一个set index,指向它的parent顶点。每个数字顶点都有一个root,如果两个顶点的root一样,则表示它们是连接的。

Weighted Quick Union:

总是把小的树作为子树。Always put smaller tree below. 树最深为lgN

Path Compression:

所经路径顶点都指向root。

WQUPC:

public class QuickUnion {private int[] id;private int[] size;public QuickUnion(int N) {id = new int[N];size = new int[N];for (int i = 0; i < N; i++) {id[i] = i;size[i] = 1;}}private int root(int i) {while (i != id[i]) {id[i] = id[id[i]]; // Path compressioni = id[i];}return i;// return i == id[i] ? i : root(id[i]); no path compression}public boolean connected(int p, int q) {return root(p) == root(q);}public void union(int p, int q) {int proot = root(p);int qroot = root(q);if (proot == qroot) {return;}// Smaller tree as subtree of larger treeif (size[proot] < size[qroot]) {id[proot] = qroot;size[qroot] += size[proot];} else {id[qroot] = proot;size[proot] += size[qroot];}}}

应用:

Percolation:

黑白块,如果从上到下有白块通路,则system percolates。


0

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63


0

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63


public class Percolation {private int[] id;private int[] size;private boolean[] color;private int width;private int top;private int bot;public Percolation(int N) {width = N;top = N * N;bot = top + 1;id = new int[N * N + 2];size = new int[N * N + 2];color = new boolean[N * N + 2];for (int i = 0; i < N * N + 2; i++) {id[i] = i;size[i] = 1;}color[top] = true;color[bot] = true;}private int root(int i) {while (i != id[i]) {id[i] = id[id[i]];i = id[i];}return i;}public boolean connected(int p, int q) {return root(p) == root(q);}public void union(int p, int q) {int proot = root(p);int qroot = root(q);if (proot == qroot) {return;}if (size[proot] <= size[qroot]) {id[proot] = qroot;size[qroot] += size[proot];} else {id[qroot] = proot;size[proot] += size[qroot];}}public void openSite(int p) {color[p] = true;if (p < width) {union(p, top);}if (p >= (width - 1) * width) {union(p, bot);}int row = p / width;int col = p % width;if (row - 1 >= 0 && color[p - width]) {union(p, p - width);}if (row + 1 < width && color[p + width]) {union(p, p + width);}if (col - 1 >= 0 && color[p - 1]) {union(p, p - 1);}if (col + 1 < width && color[p + 1]) {union(p, p + 1);}}public boolean isPercolate() {return root(top) == root(bot);}@Overridepublic String toString() {StringBuffer sb = new StringBuffer();for (int i = 0; i < width * width; i++) {if (color[i]) {sb.append("O");} else {sb.append("X");}if ((i + 1) % width == 0) {sb.append('\n');}}sb.deleteCharAt(sb.length() - 1);return sb.toString();}}

0 0
原创粉丝点击