【九度OJ】1024【并查集】【BST】【畅通工程系列2007】
2014-08-21 21:54
399 查看
先用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 ; size = new int ; 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]; } } }
相关文章推荐
- 【九度OJ】1017【BST】【畅通工程系列2006】
- 【九度OJ】1012【树】【并查集】【畅通工程系列2005】
- 九度oj 1024 (杭电)畅通工程
- 九度oj 题目1024:畅通工程 【ZJU2007考研机试题5】
- 题目1024:畅通工程 九度OJ
- 【九度OJ】题目1024:畅通工程 解题报告
- 九度OJ 1024:畅通工程
- HDU 1863 畅通工程(九度OJ 1024)
- 【九度OJ】1028【快排】【kruskal】【畅通工程系列2008】
- 九度OJ 1012:畅通工程 (最小生成树)
- 杭电oj 1232 NYOJ 5198 畅通工程(并查集)
- 九度OJ 1024 畅通工程 -- 并查集、贪心算法(最小生成树)
- 九度OJ 1028:继续畅通工程 (最小生成树)
- 九度oj 题目1012:畅通工程 【ZJU2005机试题3】
- 杭电OJ——1232 畅通工程(并查集)
- 九度OJ 1012:畅通工程 (最小生成树)
- 九度OJ 题目1017:还是畅通工程 (最小生成树)
- 九度OJ:题目 1028 继续畅通工程
- HDU 1233 还是畅通工程 (九度OJ 1017)
- HDU 1879 继续畅通工程(九度OJ 1028)