题意:
判断最小生成树是不是唯一,我的判断方法是求次小生成树,如果相等那么说明不唯一。
代码:
1 /* 2 POJ 1679:判断最小生成树是否唯一 3 思路:先求出最小生生成树 MST,再求出次小生成树SST,判断是否相等。 4 求SST:先求最小生成树,标记构成最小生成树的每一条边,然后依次删除,再次求最小生成树,取这里面的最小的即是次小生成树 5 算法实现:kruskal 6 错误:删除一条属于MST的边时,应该考虑到,有可能构造不成生成树了,所以有必要返回 -1 判断下(WA了好几次)。 7 */ 8 import java.util.Scanner; 9 import java.util.Comparator; 10 import java.util.Arrays; 11 12 class Node{ 13 public int u, v, w, mark; 14 } 15 //结构排序 16 class mycmp implements Comparator<Node>{ 17 public int compare(Node A, Node B){ 18 return A.w - B.w; 19 } 20 } 21 public class Main { 22 final static int MAXN = 10000 + 13; 23 final static int INF = 0x3f3f3f3f; 24 static int[] pre = new int[MAXN]; 25 static Node[] map = new Node[MAXN]; 26 public static void main(String[] args){ 27 Scanner sc = new Scanner(System.in); 28 int T = sc.nextInt(); 29 while(T != 0){ 30 int N,M; 31 N = sc.nextInt(); 32 M = sc.nextInt(); 33 for(int i = 1; i <= M; i++){ 34 map[i]=new Node(); 35 map[i].u = sc.nextInt(); 36 map[i].v = sc.nextInt(); 37 map[i].w = sc.nextInt(); 38 map[i].mark = 0; 39 } 40 mst(N); 41 Arrays.sort(map, 1, M + 1, new mycmp()); 42 int mst = ksu(N, M); // MST 43 int sst = INF + 1; //SST 初始化 44 for(int i = 1; i <= M; i++){ //求SST 45 if(map[i].mark == 1){ //这条边属于MST 46 mst(N); 47 int temp = ksu(N, M, i); //删除一条边后得到的结果、如果大于 0 说明构造成功,否则构造失败 48 if(temp < sst && temp != -1){ 49 sst = temp; 50 } 51 } 52 } 53 if(sst == mst){ 54 System.out.println("Not Unique!"); 55 } 56 else{ 57 System.out.println(mst); 58 } 59 T--; 60 } 61 sc.close(); 62 } 63 public static int ksu(int N, int M){ //求MST 64 int cnt = 0; 65 int ans= 0; 66 for(int i = 1; i <= M; i++){ 67 int fu = Find(map[i].u); 68 int fv = Find(map[i].v); 69 if(fu != fv){ 70 ans += map[i].w; 71 cnt++; 72 pre[fv] = fu; 73 map[i].mark = 1; //标记 74 } 75 if(cnt == N - 1){ 76 return ans; 77 } 78 } 79 return ans; 80 } 81 public static int ksu(int N, int M,int mark){ //删除 mark 这条边 求 MST 82 int ans= 0; 83 int cnt = 0; 84 for(int i = 1; i <= M; i++){ 85 if(i == mark) continue; //删除 86 int fu = Find(map[i].u); 87 int fv = Find(map[i].v); 88 if(fu != fv){ 89 ans += map[i].w; 90 cnt++; 91 pre[fv] = fu; 92 } 93 if(cnt == N - 1){ 94 return ans; 95 } 96 } 97 return -1;//说明无法再生成最小生成树 98 } 99 public static int Find(int x){ 100 return x == pre[x] ? x : (pre[x] = Find(pre[x])); 101 } 102 public static void debug(int M){ 103 for(int i = 1; i <= M; i++){ 104 System.out.println(i + " " + map[i].u + " " + map[i].v + " " + map [i].w + " "+ map[i].mark); 105 } 106 } 107 public static void mst(int N){ 108 for(int i = 1; i <= N; i++){ 109 pre[i] = i; 110 } 111 } 112 }