lightoj 1029 最小生成树 + 最大生成树

题意,给出若干条连接两个屋子间的路线的价格(保证一定都能联通),问联通所有屋子的最大代价和最小代价的平均值为多少。

分析,即求一次最大生成树,一次最小生成树

 1 /* When all else is lost the future still remains. */
 2 #define rep(X,Y,Z) for(int X=(Y);X<(Z);X++)
 3 #define drep(X,Y,Z) for(int X=(Y);X>=(Z);X--)
 4 #define fi first
 5 #define se second
 6 #define mk(X,Y) make_pair((X),(Y))
 7 //head
 8 #include <iostream>
 9 #include <stdio.h>
10 #include <queue>
11 #include <algorithm>
12 using namespace std;
13 #define MAXN 110
14 pair<int,pair<int,int> > wire[12010];
15 int rp[MAXN];
16 void init(){
17     rep(i,0,MAXN) rp[i] = i;
18     return ;
19 }
20 int f(int x){
21     return rp[x] = (rp[x] == x) ? x : f(rp[x]);
22 }
23 int MST(int n){
24     init();
25     int ans = 0;
26     rep(i,0,n){
27         int val = wire[i].fi;
28         int a = f(wire[i].se.fi);
29         int b = f(wire[i].se.se);
30         if(a == b) continue;
31         rp[a] = min(a,b);
32         rp[b] = min(a,b);
33         ans += val;
34     }
35     return ans;
36 }
37 int DMST(int n){
38     init();
39     int ans = 0;
40     drep(i,n-1,0){
41         int val = wire[i].fi;
42         int a = f(wire[i].se.fi);
43         int b = f(wire[i].se.se);
44         if(a == b) continue;
45         rp[a] = min(a,b);
46         rp[b] = min(a,b);
47         ans += val;
48     }
49     return ans;
50 }
51 int main(){
52     int T;
53     scanf("%d",&T);
54     rep(ca,1,T+1){
55         int num;
56         scanf("%d",&num);
57         int cnt = 0;
58         while(1){
59             int w , u , v;
60             scanf("%d %d %d",&u,&v,&w);
61             if(!u&&!v&&!w) break;
62             wire[cnt++] = mk(w,mk(u,v));
63         }
64         sort(wire,wire+cnt);
65         int ansA = MST(cnt);
66         int ansB = DMST(cnt);
67         printf("Case %d: ",ca);
68         if((ansA + ansB) % 2 == 0) printf("%d\n", (ansA + ansB) / 2);
69         else printf("%d/2\n",ansA + ansB);
70     }
71     return 0;
72 }

 

posted @ 2016-10-09 01:26  ACMZZ  阅读(273)  评论(0编辑  收藏  举报