HDU 1233 prim kruskal最小生成树模板题

A -  还是畅通工程
Time Limit:2000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u

Description

某省调查乡村交通状况,得到的统计表中列出了任意两村庄间的距离。省政府“畅通工程”的目标是使全省任何两个村庄间都可以实现公路交通(但不一定有直接的公路相连,只要能间接通过公路可达即可),并要求铺设的公路总长度为最小。请计算最小的公路总长度。  
 

Input

测试输入包含若干测试用例。每个测试用例的第1行给出村庄数目N ( < 100 );随后的N(N-1)/2行对应村庄间的距离,每行给出一对正整数,分别是两个村庄的编号,以及此两村庄间的距离。为简单起见,村庄从1到N编号。   当N为0时,输入结束,该用例不被处理。 
 

Output

对每个测试用例,在1行里输出最小的公路总长度。  
 

Sample Input

3 1 2 1 1 3 2 2 3 4 4 1 2 1 1 3 4 1 4 1 2 3 3 2 4 2 3 4 5 0
 

Sample Output

3 5

Hint

Hint  Huge input, scanf is recommended.

第一道最小生成树的题目,以此题作为模板。
Prim算法
 1 #include <iostream>
 2 using namespace std;
 3 #define INF 999999999
 4 
 5 int map[101][101],visit[101],dis[101],N;
 6 int prim()
 7 {
 8     for(int i = 2; i <= N; i++)
 9     {
10         visit[i] = 0;
11         dis[i] = map[i][1];
12     }
13     visit[1] = 1;
14     int sum = 0;
15     for(int i = 1; i <= N-1; i++)
16     {
17         int temp = INF,pos; 
18         for(int j = 1; j <= N; j++)
19         {
20             if(!visit[j] && dis[j] < temp)
21             {
22                 temp = dis[j];
23                 pos = j;
24             }    
25         }
26         visit[pos] = 1;
27         sum += dis[pos];
28         for(int j = 1; j <= N; j++)
29         {
30             if(!visit[j] && dis[j] > map[pos][j] && map[pos][j]!= INF)
31                 dis[j] = map[pos][j];
32         }
33     }
34     return sum;
35 } 
36 
37 int main()
38 {
39     while(scanf("%d",&N),N)
40     {
41         int u,v,w;
42         for(int i = 1; i <= N; i++)
43             dis[i] = INF; 
44         for(int i = 1; i <= (N*(N-1))/2; i++)
45         {
46             scanf("%d%d%d",&u,&v,&w);
47             map[u][v] = map[v][u] = w;
48         }
49         cout<<prim()<<endl;
50     }
51 }
View Code

Kruskal算法

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <algorithm>
 4 #define  maxn 103 
 5 using namespace std;
 6 
 7 int father[maxn];
 8 struct edges 
 9 {
10     int pre;
11     int suc;
12     int w;
13 }edge[5000];
14 
15 int cmp(edges x, edges y)
16 {
17     return (x.w < y.w)?1:0;
18 }
19 int find(int x)
20 {
21     if(father[x] == x)return x;
22     return father[x] = find(father[x]);
23 }
24 int kruskal(int n,int es)
25 {
26     for(int i = 1; i <= n; i++)
27     {
28         father[i] = i;
29     }
30     sort(edge+1,edge+1+es,cmp);
31     int sum = 0;
32     for(int i = 1; i <= es; i++)
33     {
34         int fx = find(edge[i].pre),fy = find(edge[i].suc);
35         if(fx != fy)
36         {
37             father[fx] = fy;
38             sum += edge[i].w;
39         }
40     }
41     return sum;
42 }
43 int main()
44 {
45     int  n,es;
46     while(scanf("%d",&n),n)
47     {
48         es = (n*(n-1))/2;
49         for(int i = 1; i <= es; i++)
50         {
51             scanf("%d%d%d",&edge[i].pre,&edge[i].suc,&edge[i].w);
52         }
53         int ans = kruskal(n,es);
54         printf("%d\n",ans);
55     }
56     
57 } 
View Code

 

 

转载于:https://www.cnblogs.com/CrazyBaby/p/5432841.html

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值