题意:
判断最小生成树是不是唯一,我的判断方法是求次小生成树,如果相等那么说明不唯一。
代码:
/* POJ 1679:判断最小生成树是否唯一 思路:先求出最小生生成树 MST,再求出次小生成树SST,判断是否相等。 求SST:先求最小生成树,标记构成最小生成树的每一条边,然后依次删除,再次求最小生成树,取这里面的最小的即是次小生成树 算法实现:kruskal 错误:删除一条属于MST的边时,应该考虑到,有可能构造不成生成树了,所以有必要返回 -1 判断下(WA了好几次)。 */ import java.util.Scanner; import java.util.Comparator; import java.util.Arrays; class Node{ public int u, v, w, mark; } //结构排序 class mycmp implements Comparator<Node>{ public int compare(Node A, Node B){ return A.w - B.w; } } public class Main { final static int MAXN = 10000 + 13; final static int INF = 0x3f3f3f3f; static int[] pre = new int[MAXN]; static Node[] map = new Node[MAXN]; public static void main(String[] args){ Scanner sc = new Scanner(System.in); int T = sc.nextInt(); while(T != 0){ int N,M; N = sc.nextInt(); M = sc.nextInt(); for(int i = 1; i <= M; i++){ map[i]=new Node(); map[i].u = sc.nextInt(); map[i].v = sc.nextInt(); map[i].w = sc.nextInt(); map[i].mark = 0; } mst(N); Arrays.sort(map, 1, M + 1, new mycmp()); int mst = ksu(N, M); // MST int sst = INF + 1; //SST 初始化 for(int i = 1; i <= M; i++){ //求SST if(map[i].mark == 1){ //这条边属于MST mst(N); int temp = ksu(N, M, i); //删除一条边后得到的结果、如果大于 0 说明构造成功,否则构造失败 if(temp < sst && temp != -1){ sst = temp; } } } if(sst == mst){ System.out.println("Not Unique!"); } else{ System.out.println(mst); } T--; } sc.close(); } public static int ksu(int N, int M){ //求MST int cnt = 0; int ans= 0; for(int i = 1; i <= M; i++){ int fu = Find(map[i].u); int fv = Find(map[i].v); if(fu != fv){ ans += map[i].w; cnt++; pre[fv] = fu; map[i].mark = 1; //标记 } if(cnt == N - 1){ return ans; } } return ans; } public static int ksu(int N, int M,int mark){ //删除 mark 这条边 求 MST int ans= 0; int cnt = 0; for(int i = 1; i <= M; i++){ if(i == mark) continue; //删除 int fu = Find(map[i].u); int fv = Find(map[i].v); if(fu != fv){ ans += map[i].w; cnt++; pre[fv] = fu; } if(cnt == N - 1){ return ans; } } return -1;//说明无法再生成最小生成树 } public static int Find(int x){ return x == pre[x] ? x : (pre[x] = Find(pre[x])); } public static void debug(int M){ for(int i = 1; i <= M; i++){ System.out.println(i + " " + map[i].u + " " + map[i].v + " " + map [i].w + " "+ map[i].mark); } } public static void mst(int N){ for(int i = 1; i <= N; i++){ pre[i] = i; } } }