UVA 1395 Slim Span 最小生成樹

題意:java

  給你一個圖,讓你求這個圖中全部生成樹中知足題目條件的,這個條件是生成樹中最長邊與最短邊的差值最小。算法

思路:spa

  根據最小瓶頸生成樹的定義:在一個有權值的無向圖中,求一個生成樹最大邊的權值儘可能小。首先以K算法作這道題,先給全部邊排好序,而後我能夠從小到大枚舉每一條邊做爲我所求生成樹的最短邊(即第一次以最短邊求最小生成樹,第二次刪除第一條邊,以第二條邊爲最短邊求最小生成樹,第三次刪除第一條邊和第二條邊,以第三邊爲最短邊求最小生成樹。)而後在這個過程當中更新   MST(maxE- minE)就行了。這麼作的緣由是:由於最小生成樹必定是無向圖的瓶頸生成樹。即若是最短邊(第一條邊)已經定下來,那麼最小生成樹的 (maxE- minE)必定比其餘以這個邊爲最短邊的生成樹的(maxE - min E)小。因此就能夠依次枚舉這個最短邊,更新答案就行了。debug

代碼:code

 

 1 import java.util.Scanner;
 2 import java.util.Comparator;
 3 import java.util.Arrays;
 4 
 5 class Node{
 6     public int u, v, w, mark;
 7 }
 8 //結構排序
 9 class mycmp implements  Comparator<Node>{
10     public int compare(Node A, Node B){ 
11                 return A.w - B.w;  
12       }  
13 }
14 public class Main {
15     final static int MAXN = 10000 + 13;
16     final static int INF = 0x3f3f3f3f;
17     static int[] pre = new int[MAXN];
18     static Node[] map = new Node[MAXN];
19     public static void main(String[] args){
20         Scanner sc = new Scanner(System.in);
21         while(true){
22             int N,M;
23             N = sc.nextInt();
24             M = sc.nextInt();
25             if(N == 0 && M == 0)break;
26             for(int i = 1; i <= M; i++){
27                 map[i]=new Node();  
28                 map[i].u = sc.nextInt();
29                 map[i].v = sc.nextInt();
30                 map[i].w = sc.nextInt();
31                 map[i].mark = 0;
32             }
33             met(N);
34             Arrays.sort(map, 1, M + 1, new mycmp());
35             int sst = ksu(N, M, 0);    //SST 初始化爲最小生成樹的值
36             for(int i = 1; i <= M; i++){ //求SST
37                     met(N);
38                     int temp = ksu(N, M, i);//以第 i + 1 條邊做爲第一條邊(即刪除前i條邊後)求MST,若是不等於 -1 說明構形成功
39                     if(temp < sst && temp != -1){ 
40                         sst = temp;
41                 }
42             }
43             System.out.println(sst);
44         }
45         sc.close();
46     }
47     public static int ksu(int N, int M,int mark){  //刪除 前 mark 條邊 求 MST
48         int cnt= 0;
49         int st, ed;
50         st = ed = map[1].w;
51         boolean flag = true;
52         for(int i = mark + 1; i <= M; i++){
53             int fu = Find(map[i].u);
54             int fv = Find(map[i].v);
55             if(fu != fv){
56                 if(flag){
57                     st = map[i].w;
58                     flag = false;
59                 }
60                 cnt++;
61                 pre[fv] = fu;
62             }
63             if(cnt == N - 1){
64                 ed = map[i].w;
65                 return ed - st;
66             }
67         }
68         return -1;
69     }
70     public static int Find(int x){
71         return x == pre[x] ? x : (pre[x] = Find(pre[x]));
72     }
73     public static void debug(int M){
74         for(int i = 1; i <= M; i++){
75             System.out.println(i + " " + map[i].u + " " + map[i].v + " " + map [i].w + " "+ map[i].mark);
76         }
77     }
78     public static void met(int N){
79         for(int i = 1; i <= N; i++){
80             pre[i] = i;
81         }
82     }
83 }
相關文章
相關標籤/搜索