码迷,mamicode.com
首页 > 其他好文 > 详细

HDU 1233 还是畅通工程(最小生成树)

时间:2014-12-31 06:16:13      阅读:217      评论:0      收藏:0      [点我收藏+]

标签:

仔细想想这就是一道最裸的最小生成树题目

这里给出prim和kruscal两种方法计算

当然因为这题目是密集边

所以其实prim算法更加好一点的

 

prim:

 1 /*
 2 最小生成树,prim算法
 3 */
 4 #include <cstdio>
 5 #include <cstring>
 6 #include <algorithm>
 7 
 8 using namespace std;
 9 const int N = 105;
10 const int INF = 0x3f3f3f3f;
11 
12 int k , fa[N] , minn[N] , first[N] , vis[N];//vis[N]表示是否添入以保存的集合
13 
14 struct Edge{
15     int y , next , d;
16     bool operator<(const Edge & m )const{
17         return d < m.d;
18     }
19 }e[N*N];
20 
21 void add_edge(int x , int y, int d)
22 {
23     e[k].y = y , e[k].next = first[x] , e[k].d = d;
24     first[x] = k++;
25 }
26 
27 int prim(int src , int n)
28 {
29     memset(minn , 0x3f , sizeof(minn));
30     memset(vis , 0 , sizeof(vis));
31     vis[src] = 1;
32     for(int i = first[src] ; i!=-1 ; i=e[i].next)
33     {
34         int v = e[i].y;
35         if(!vis[v]) minn[v] = min(minn[v] , e[i].d);
36     }
37     int ans = 0;
38     for(int i = 1 ; i<n ; i++)
39     {
40         int index = 0 , Min = INF;
41         for(int j = 1 ; j<=n ; j++)
42         {
43             if(minn[j] < Min){
44                 Min = minn[j];
45                 index = j;
46             }
47         }
48         ans += Min;
49         minn[index] = INF;
50         vis[index] = 1; //使index不能再被访问
51         //更新
52         for(int j = first[index] ; j!=-1 ; j=e[j].next)
53         {
54             int v = e[j].y;
55             if(!vis[v]) minn[v] = min(minn[v] , e[j].d);
56         }
57     }
58     return ans;
59 }
60 
61 int main()
62 {
63    // freopen("a.in" , "r" , stdin);
64     int n , m , a , b , d;
65     while(scanf("%d" , &n) , n)
66     {
67         m = n*(n-1) / 2;
68         for(int i = 1 ; i<=n ; i++) fa[i] = i;
69 
70         k = 0;
71         memset(first , -1 , sizeof(first));
72         for(int i = 0 ; i<m ; i++){
73             scanf("%d%d%d" , &a , &b , &d);
74             add_edge(a , b , d);
75             add_edge(b , a , d);
76         }
77 
78         printf("%d\n" , prim(1 , n));
79     }
80     return 0;
81 }

 

kruscal:

 1 /*
 2 最小生成树,prim算法
 3 */
 4 #include <cstdio>
 5 #include <cstring>
 6 #include <algorithm>
 7 
 8 using namespace std;
 9 const int N = 105;
10 
11 int k , fa[N];
12 
13 struct Edge{
14     int x , y , d;
15     bool operator<(const Edge & m )const{
16         return d < m.d;
17     }
18 }e[N*N];
19 
20 void add_edge(int x , int y, int d)
21 {
22     e[k].x = x , e[k].y = y , e[k].d = d;
23     k++;
24 }
25 
26 int get_head(int x)
27 {
28     while(x != fa[x]) x=fa[x];
29     return x;
30 }
31 
32 bool Union(int x , int y)
33 {
34     int fa_x = get_head(x);
35     int fa_y = get_head(y);
36     if(fa_x != fa_y){
37         fa[fa_x] = fa_y;
38         return true;
39     }
40     return false;
41 }
42 
43 int main()
44 {
45    // freopen("a.in" , "r" , stdin);
46     int n , m , a , b , d;
47     while(scanf("%d" , &n) , n)
48     {
49         k = 0;
50         m = n*(n-1) / 2;
51 
52         for(int i = 1 ; i<=n ; i++) fa[i] = i;
53 
54         for(int i = 0 ; i<m ; i++){
55             scanf("%d%d%d" , &a , &b , &d);
56             add_edge(a , b , d);
57         }
58         sort(e , e+k);
59         int ans = 0;
60         for(int i = 0 ; i<k ; i++){
61             if(Union(e[i].x , e[i].y)) ans += e[i].d;
62         }
63         printf("%d\n" , ans);
64     }
65     return 0;
66 }

 

HDU 1233 还是畅通工程(最小生成树)

标签:

原文地址:http://www.cnblogs.com/CSU3901130321/p/4194903.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!