題解西電OJ (Problem 1004 -亞特蘭提斯)--最小生成樹

Descriptionios

  爲了找尋沉睡的亞特蘭提斯大陸,wm來到了大西洋上進行探險,找了半個月仍一無所得。然而在一次突襲而來的暴風雨後,wm的船莫名地駛入了一片未知的區域,發現了一個地圖上未標記的島嶼,這讓他感到至關驚訝,強烈的好奇心驅使他上岸看看究竟。 
船在島嶼靠岸後島上的國王舉行慶典熱情地款待了他,整個島一片喜慶。國王自稱是亞特蘭提斯人,而這個島嶼曾經是亞特蘭提斯大陸的最高地。如今島嶼上還有N個城市,因爲島上的資源至關有限且島上沒人知道怎麼合理利用資源故一直以來在城市之間都沒有鋪設道路,如今國王想請wm規劃下道路並進行建設,國王對規劃的要求以下: 
  1.全部城市必須連通,即任意兩個城市均可以互相來往 
  2.國王是個嬌氣的人,因此他但願從任意城市走到任意另外一個城市時的「溫馨度」越高越好,其中兩個城市間的「溫馨度」定義爲:兩個城市間路徑的每一段道路的「溫馨度」的最小者,例如從A到B須要通過C城市,A->C段「溫馨度」爲10,C->B段「溫馨度」爲100,則A->B的「溫馨度」爲10(固然若是兩個城市間有不少路徑的話國王會走「溫馨度」最大的路徑)。如今定義K爲全部兩個城市間「溫馨度」的最小者,而國王但願K越大越好。 
  如今島上的資源只有R單位,國王但願wm幫他規劃道路知足他的要求,在島上資源條件的容許下輸出最大的K。若是島上的資源不夠知足第1個要求,則輸出-1。 
wm沉迷於島上的玩樂,懶得去想這問題了,因此他遠程求助你,幫他解決這個煩人的問題。
spa

Input
  輸入包含多組數據,EOF結束。 
  每組數據以三個整數開頭,N,M,R。N(2<=N<=1000)是城市數,M(0<=M<=100000)是容許建造的道路數,R(0<=R<=100000)是島上僅有的資源數。EOF結束。 
  接下來有M行數據,每行包括a,b(0<=a,b<N),v(0<v<=100000),c(0<=c<=100000)四個整數,表示ab城市間容許建一條雙向道路,花費v單位資源,「溫馨度」爲c。
Output
  每組數據輸出一行,島上資源條件的容許下最大的K或-1。
Sample Input
3 3 1000
0 1 20 8
1 2 10 7
2 0 10 6
3 3 20
0 1 20 8
1 2 10 7
2 0 10 6
2 1 10
0 1 20 8
Sample Output
7
6
-1
 
問題分析:
 
其實這個題就是一個最小生成樹的問題,由於題中的K,就是國王的溫馨度,須要在消耗資源R之內,建成一顆樹,聯通全部城市
那麼個人解決方案就是K的最小值爲 D 時,將全部溫馨度小於D的路均不考慮,生成最小生成樹,是否知足資源消耗小於R,K的最小值經過二分法得到。
 
代碼以下:
 
 1 #include <iostream>
 2 #include <stdlib.h>
 3 using namespace std;
 4 
 5 
 6 struct Path{
 7     int start ;
 8     int end ;
 9     int cost ;
10     int wieght ;
11 } ;
12 
13 Path path[100000] ;
14 
15 int wight[100000] ;
16 int p[1001];
17 
18 //int res ;
19 
20 int n , m , r , new_m;
21 
22 
23 
24 int find_root(int a){
25     while(a!=p[a]){
26         a = p[a] ;
27     }
28     return a;
29 }
30 
31 bool krusker(int cur_w)
32 {
33     int m_cost = 0 ;
34     int i = 0;
35     for(i = 0 ; i < n ;i++){
36         p[i] = i ;
37     }
38 
39     int x , y ;
40     int count = 0 ;
41     for(i = 0 ; i < m; i++){
42         if(path[i].wieght < cur_w){
43             continue ;
44         }
45         x = find_root(path[i].start);
46         y = find_root(path[i].end);
47         if(x!=y){            
48             m_cost += path[i].cost;
49             p[x] = y ;
50             if(m_cost > r){
51                 return false ;
52             }
53             count ++ ;
54             if(count == n-1){
55                 return true;
56             }
57         }        
58     }
59 
60     return false;
61 }
62 
63 
64 int comp1(const void *a,const void *b)
65 {
66     return (*(Path *)a).cost - (*(Path *)b).cost ;
67 }
68 
69 
70 
71 
72 int main()
73 {
74 
75     
76     while(cin >> n >> m >> r){
77 //        res = -1 ;
78         int i , j , k ;
79         int minw = 1000000 ;
80         int maxw = -1 ;
81         for(i = 0 ; i < m ; i++)
82             cin >> path[i].start >> path[i].end >> path[i].cost >> path[i].wieght ;
83         k = 0 ;
84         qsort(path,m,sizeof(Path),comp1) ;
85         int l = -1 ;
86         j = 100001;
87         while(l<j-1){
88             k = (l + j) / 2 ;
89             if(krusker(k)){
90                 l = k ;
91             }else{
92                 j = k ;
93             }
94         }
95         cout << l << endl ;
96     }
97     return 0;
98 }
相關文章
相關標籤/搜索