【九度OJ】1024【并查集】【BST】【畅通工程系列2007】

来源:互联网 发布:格式工厂 for mac 编辑:程序博客网 时间:2024/05/29 17:05

先用1012题的思路,判断是否有能连通。用图的邻接矩阵,prime算法求BST

代码:

package Test1;import java.io.BufferedReader;import java.io.IOException;import java.io.InputStreamReader;import java.io.StreamTokenizer;public class Test37_1024 {/** * by qr jobdu 1024 2014-8-19 *  * @throws IOException */public static void main(String[] args) throws IOException {StreamTokenizer st = new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));int n, m;while (true) {st.nextToken();n = (int) st.nval; // 道路数目st.nextToken();m = (int) st.nval; // 村庄数目if (n == 0)break;int arr[][] = new int[m + 1][m + 1]; // 无穷(用很大的数代替)代表没有路,非0代表有路for (int i = 0; i <= m; i++)for (int j = 0; j <= m; j++) {arr[i][j] = Integer.MAX_VALUE;}UnionFindSet ufs = new UnionFindSet(m + 1);// 延续1012题的思路,先判断是否可以实现相通int n1, n2, weight, num = 0;for (int i = 0; i < n; i++) {st.nextToken();n1 = (int) st.nval;st.nextToken();n2 = (int) st.nval;st.nextToken();weight = (int) st.nval;// 去重复边??if (arr[n1][n2] == 0) {arr[n1][n2] = weight;arr[n2][n1] = weight;} else {arr[n1][n2] = Math.min(arr[n1][n2], weight);arr[n2][n1] = Math.min(arr[n1][n2], weight);}if (ufs.find(n1) != ufs.find(n2)) {ufs.union(n1, n2);num++;}}if (num >= (m - 1)) { // 可以相通,求BST(prim)int flag[] = new int[m + 1];// 0代表该顶点不在集合U中,1代表在集合U中flag[1] = 1; // 从顶点1开始int pos = 1; // 目前的顶点int numedge = 0; // 代表加入TE中的边的个数int wei = 0; // BST的权重之和int min[] = new int[m + 1]; // 边的权重for (int i = 1; i <= m; i++) {min[i] = arr[pos][i];}while (true) {int minmin = Integer.MAX_VALUE;int lastpos=pos;for (int i = 1; i <= m; i++) {if (flag[i] == 0 && min[i] < minmin) {minmin = min[i];lastpos=pos;pos = i;}}flag[pos] = 1;for (int i = 1; i <= m; i++) {if (flag[i] == 0 && min[i] > arr[pos][i])min[i] = arr[pos][i];}//wei += arr[lastpos][pos];wei+=min[pos];//!!!!numedge++; // 名字一定要区分开使用范围,不然容易出错if (numedge == (m - 1))break;}System.out.println(wei);} else { // 不能相通System.out.println("?");}}}}class UnionFindSet {int set[];int size[];UnionFindSet() {}UnionFindSet(int n) {set = new int[n];size = new int[n];for (int i = 0; i < n; i++) {set[i] = i;size[i] = 1;}}int find(int i) {while (i != set[i]) {i = set[i];}return i;}void union(int i, int j) {int p = find(i);int q = find(j);if (size[p] < size[q]) {set[p] = q;size[q] += size[p]; // 勿忘修改size} else {set[q] = p;size[p] += size[q];}}}


0 0
原创粉丝点击