




package com.tiger.study.DataStructure.uf;public class UF {// 记录结点元素和改元素所在分组的标识private int[] eleAndGroup;// 记录并查集中数据的分组个数private int count;// 初始化并查集public UF(int N) {// 初始化分组的数量,默认情况下有N个数组this.count = N;// 初始化eleAndGroup数组this.eleAndGroup = new int[N];// 初始化eleAndGroup中的元素及其所在的组的标识符,让eleAndGroup数组的索引作为并查集每个索引处的值(该元素所在的组的标识符)就是该索引for (int i = 0; i < eleAndGroup.length; i++) {eleAndGroup[i] = i;}}// 获取当前并查集中有多少个分组public int count() {return count;}// 元素p所在的分组的标识符public int find(int p) {return eleAndGroup[p];}// 判断并查集中元素p和元素q是否是在同一个分组中public boolean connected(int p, int q) {return find(p) == find(q);}// 把p元素所在分组和q元素所在分组合并public void union(int p, int q) {// 判断元素q和p是否在同一分组中,如果在结束if (connected(p, q)) {return;}// 找到p所在的标识符int pGroup = find(p);// 找到q所在的标识符int qGroup = find(q);// 合并组:让p所在组的所有元素的组的标识符变为q所在分组的标识符for (int i = 0; i < eleAndGroup.length; i++) {if (eleAndGroup[i] == pGroup) {eleAndGroup[i] = qGroup;}}this.count--;}}




package com.tiger.study.DataStructure.uf;public class UF_Tree {// 记录结点元素和该结点所在分组的标识private int[] eleAndGroup;// 记录并查集中的数据分组的个数private int count;// 初始化并查集public UF_Tree(int N) {// 初始化分组的数量,默认情况下有N个分组this.count = N;// 初始化分组的数量,默认情况下,有N个分组this.count = N;// 初始化eleAndGroup数组this.eleAndGroup = new int[N];// 初始化eleAndGroup中的元素及其所在的组的标识符,让eleAndGroup数组的索引作为并查集每个索引处的值(该元素所在的组的标识符)就是该索引for (int i = 0; i < eleAndGroup.length; i++) {eleAndGroup[i] = i;}}// 获取当前并查集中的数据有多少个分组public int count() {return count;}// 判断并查集中元素p和元素q是否是在同一个分组中public boolean connected(int p, int q) {return find(p) == find(q);}// 元素p所在的分组的标识符public int find(int p) {while (true) {if (p == eleAndGroup[p]) {return p;}p = eleAndGroup[p];}}// 把p元素所在分组和q元素所在分组合并public void union(int p, int q) {// 找到p和q所在组对应树的的根结点int pRoot = find(p);int qRoot = find(q);// 如果p和q已经在同一分组,则不需要合并了if (pRoot == qRoot) {return;}// 让p所在树的根结点的父结点为q所在树的根结点即可eleAndGroup[pRoot] = qRoot;this.count--;}}


package com.tiger.study.DataStructure.uf;public class UF_Tree_Weighted {// 记录结点元素和该结点所在分组的标识private int[] eleAndGroup;// 记录并查集中的数据分组的个数private int count;// 用来存储每一个根结点对应的树中保存的结点的个数private int[] sz;// 初始化并查集public UF_Tree_Weighted(int N) {// 初始化分组的数量,默认情况下有N个分组this.count = N;// 初始化分组的数量,默认情况下,有N个分组this.count = N;// 初始化eleAndGroup数组this.eleAndGroup = new int[N];// 默认情况下sz中每一个元素的值都是1this.sz = new int[N];for (int i = 0; i < sz.length; i++) {sz[i] = 1;}// 初始化eleAndGroup中的元素及其所在的组的标识符,让eleAndGroup数组的索引作为并查集每个索引处的值(该元素所在的组的标识符)就是该索引for (int i = 0; i < eleAndGroup.length; i++) {eleAndGroup[i] = i;}}// 获取当前并查集中的数据有多少个分组public int count() {return count;}// 判断并查集中元素p和元素q是否是在同一个分组中public boolean connected(int p, int q) {return find(p) == find(q);}// 元素p所在的分组的标识符public int find(int p) {while (true) {if (p == eleAndGroup[p]) {return p;}p = eleAndGroup[p];}}// 把p元素所在分组和q元素所在分组合并public void union(int p, int q) {// 找到p和q所在组对应树的的根结点int pRoot = find(p);int qRoot = find(q);// 如果p和q已经在同一分组,则不需要合并了if (pRoot == qRoot) {return;}// 判断pRoot对应的树大,还是qRoot对应的树大,最终需要把较小的树合并到较大的树中if (sz[pRoot] < sz[qRoot]) {eleAndGroup[pRoot] = qRoot;sz[qRoot] += sz[pRoot];} else {eleAndGroup[qRoot] = pRoot;sz[pRoot] += sz[qRoot];}this.count--;}}

package com.tiger.study.DataStructure.Test.UF;import com.tiger.study.DataStructure.uf.UF_Tree_Weighted;import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;public class Traffic_Project_Test {public static void main(String[] args) throws IOException {// 构建一个缓冲读取流BufferReaderBufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream("D:\\Study_Code\\src\\main\\java\\com\\tiger\\study\\DataStructure\\Test\\UF\\traffic_project.txt")));// 读取第一行数据20int totalNumber = Integer.parseInt(br.readLine());// 构建并查集对象UF_Tree_Weighted uf = new UF_Tree_Weighted(totalNumber);// 读取第二行数据7代表已经修好了多少条到了int roadNumber = Integer.parseInt(br.readLine());// 循环读取7条道路for (int i = 0; i < roadNumber; i++) {String line = br.readLine();String[] str = line.split(" ");int p = Integer.parseInt(str[0]);int q = Integer.parseInt(str[1]);// 调用并查集对象union方法让两个城市相通uf.union(p, q);}// 获取当前并查集分组的数量-1就可以得到还需要修建的道路的数量int roads = uf.count() - 1;System.out.println("还需要修建" + roads + "条道路才能实现畅通工程。");}
}
上一篇:路过旧居,遇见邻居的儿子