hdu 1233 还是畅通工程

这道题 就是简单的最小生成树算法的应用啦,很明显的..而且把所有边都给出来了,所以就试着自己把prim和kruscal一起实现了.

1.prim算法实现

 1 #include<iostream>
 2 #include<stdio.h>
 3 #include<string.h>
 4 #include<algorithm>
 5 using namespace std;
 6 #define maxn 105
 7 #define INF 0x3f3f3f3f
 8 bool visit[maxn];
 9 int cost[maxn][maxn];
10 int mincost[maxn];
11 int n,min_cost,index;
12 int prim()
13 {
14     int res = 0, index = 1;
15     for(int i = 1;i <= n;i++)
16         mincost[i] = cost[i][1];
17     mincost[1] = 0;
18     memset(visit,false,sizeof(visit));
19     visit[1] = true;
20     for(int i = 1 ; i <= n; i++)
21     {
22         min_cost = INF;
23         for(int j = 1; j <= n; j++)
24         {
25             if(mincost[j]<min_cost && !visit[j])
26             {
27                 min_cost = mincost[j];
28                 index = j;
29             }
30         }
31         visit[index] = true;
32         for(int k = 1; k <= n; k++)
33         {
34             if(!visit[k] && cost[k][index] < mincost[k])
35                 mincost[k] = cost[k][index] ;
36             
37         }
38         
39     }
40     for(int i = 1 ;i <=n;i++)
41         res += mincost[i];
42     return res;
43 }
44 int main()
45 {
46     //freopen("hdu 1233.txt","r",stdin);
47     int a,b,d;
48     while(scanf("%d",&n),n)
49     {
50         memset(cost,INF,sizeof(cost));
51         for(int i = 0 ;i < n * (n-1) / 2 ; i ++ )
52         {
53             scanf("%d %d %d",&a,&b,&d);
54             cost[a][b] = cost[b][a] = d;
55         }
56         printf("%d\n",prim());
57     }
58      
59     return 0;
60     
61 }
View Code


2.通过stl库的优先队列实现的kruscal算法

因为只用到了并查集的简单合并,所以并没有通过秩来进行合并,没有必要做冗余的步骤.这题可能数据量比较小,用优先队列并没有起到运行速度优化的作用.

 1 #include <iostream>
 2 #include <stdio.h>
 3 #include <string.h>
 4 #include <queue>
 5 using namespace std;
 6 #define maxn 105
 7 int father[maxn];
 8 int n;
 9 struct node{
10     int u , v;
11     int cost ;
12     friend bool operator < ( node a,  node b){
13         return a.cost > b.cost;
14     };
15 };
16 priority_queue<node> game;
17 void init()
18 {
19    for(int i = 1 ;i <= n; i++)
20    {
21        father[i] = i;
22    }
23 }
24 int find(int x)
25 {
26    if(father[x] == x)
27        return x;
28    return father[x] = find(father[x]);
29 }
30 void unite(int x,int y)
31 {
32     int fx = find(x),fy = find(y);
33     if(fx == fy) 
34         return ;
35     father[fy] = fx;
36 }
37 int kruscal()
38 {
39     int count = 0 ,res = 0;
40     node q;
41     while(!game.empty())
42     {
43         q = game.top();
44         game.pop();
45         if(count == n )
46             return res;
47         if( find(q.u)!=find(q.v))    
48         {
49             unite(q.u,q.v);
50             count++;
51             res += q.cost;
52         }
53     }    
54     return res;
55 }
56 int main()
57 {
58     //freopen("hdu 1233.txt","r",stdin);
59     int a,b,d,t;
60     while(scanf("%d",&n),n)
61     {
62         init();
63         t = 0; node s;
64         for(int i = 0 ;i < n * (n-1) / 2 ; i ++ )
65         {
66             scanf("%d %d %d",&a,&b,&d);
67             //cost[a][b] = cost[b][a] = d;
68             s.u = a ;
69             s.v = b;
70             s.cost = d;
71             game.push(s);
72         }
73         printf("%d\n",kruscal());
74     }
75     return 0;
76 }
View Code

3.通过结构体数组记录边与定点信息实现的kruscal算法

 1 #include <iostream>
 2 #include <stdio.h>
 3 #include <string.h>
 4 #include <algorithm>
 5 using namespace std;
 6 #define maxn 105 * 60
 7 #define  INF 0x3f3f3f3f
 8 int father[maxn];
 9 int n;
10 struct node{
11     int u , v;
12     int w;
13 }edge[maxn];
14 void init()
15 {
16     for(int i = 0 ;i <= n ;i++)
17             father[i] = i;
18 }
19 int find(int x)
20 {
21     if(father[x]==x)
22        return x;
23     return father[x]=find(father[x]);
24 }
25 void unite(int x,int y)
26 {
27     int fx = find(x) , fy = find(y);
28     if(fx == fy)
29          return ;
30     father[fy] = fx;
31 }
32 bool cmp(node a , node b)
33 {
34     return a.w < b.w;
35 }
36 int kruscal(int t)
37 {
38     int res = 0,count = 0;
39     int u,v;
40     for(int i = 0 ;i < t; i++)
41     {
42         u = edge[i].u;
43         v = edge[i].v;
44         if(count == n)
45             return res;
46         if(find(u)!=find(v))
47         {
48             unite(u,v);
49             count++;
50             res += edge[i].w;
51 
52         }
53 
54     }
55     return res;
56 }
57 int main()
58 {
59     //freopen("hdu 1233.txt","r",stdin);
60     int a,b,d;
61     int t ;
62     while(scanf("%d",&n),n)
63     {
64         init();
65         t= 0;
66         for(int i = 0 ;i < n*(n-1)/2 ; i++)
67         {
68             scanf("%d %d %d",&a,&b,&d);
69             edge[t].u = a;
70             edge[t].v = b;    
71             edge[t++].w = d;        
72         }
73         sort(edge,edge+t,cmp);
74         printf("%d\n",kruscal(t));
75     }
76     return 0;
77 }
View Code

值得注意的是,排序是对所有读入的数据排序,不是对前n个数据排序,因为给出的数据量很小,所以一些细节错误是不容易看出来的..所以因为这个折腾了一会才发现,写的时候没发现,

对比了自己的代码半天,最后会宿舍重新检查一下就发现了.总之,就是做事情要细心,不能想当然.

转载于:https://www.cnblogs.com/xiaoniuniu/p/4391284.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值