HDU 1301 Jungle Roads

这一题是比较水的最小生成树的题,作为模板题比较好,下面给出了prim算法跟kruskal算法的源代码。

AC code:

kruskal
 1 //kruskal
 2 #include <iostream>
 3 #include <algorithm>
 4 using namespace std;
 5 const int MAX = 30;
 6 int father[MAX];
 7 int n, sum;
 8 int roadNumber;
 9 struct ROAD{
10     int s, e, v;
11 }road[MAX * MAX];
12 
13 
14 void init()     //对并查集初始化
15 {
16     for (int i = 1; i <= n; i++)
17     {
18          father[i] = i;
19     } 
20 }
21 int cmp(ROAD a, ROAD b)
22 {
23     return a.v < b.v;
24 }
25 int find(int k)      //使用并查集判断是否产生了回路
26 {
27     return k == father[k] ? k : father[k] = find(father[k]);
28 }
29 void kruskal()
30 {
31     int i;
32     for(i = 0; i < roadNumber; i++)
33     {
34          int s = find(road[i].s);
35          int e = find(road[i].e);
36          if (s != e)
37          {
38              sum += road[i].v;
39              father[s] = e;
40          }
41     }
42 }
43 int main()
44 {
45     while(scanf("%d", &n) != EOF && n)
46     {
47         int i, j, temp, tv;
48         char a, b;
49         roadNumber = 0, sum = 0;
50         init();
51         for(i = 0; i < n - 1; i++)
52         {
53             cin >> a >> temp;
54             for(j = 0; j < temp; j++)
55             {
56                 cin >> b >> tv;
57                 road[roadNumber].s = a - 'A' + 1;
58                 road[roadNumber].e = b - 'A' + 1;
59                 road[roadNumber++].v = tv;
60             }
61         }
62         sort(road, road + roadNumber, cmp);    //对所有边按升序排序
63         kruskal();
64         cout << sum << endl;
65     }
66     return 0;
67 }
prim
 1 //prim
 2 #include <iostream>
 3 using namespace std;
 4 const int MAX = 30;
 5 const int INF = 100000;
 6 int closedge[MAX];
 7 int map[MAX][MAX];
 8 int n, vis[MAX], sum;
 9 
10 void prim()
11 {
12      int i, j;
13      for(i = 1; i <= n; i++){
14          closedge[i] = INF;
15      }
16      memset(vis, 0, sizeof(vis));
17      closedge[1] = 0;
18      for(i = 1; i <= n; i++){
19         int min = INF;
20         int pos = -1;
21         for(j = 1; j <= n; j++){          //找出未加入生成树的点到已生成的最小生成树的最短距离
22             if(!vis[j] && closedge[j] < min){
23                 min = closedge[j];
24                 pos = j;
25             }
26         }
27         vis[pos] = 1;
28         sum += min;
29         for(j = 1; j <= n; j++){             //松弛操作,将到新加入的点距离最小的value赋给closedge
30             if(map[pos][j] < closedge[j] && !vis[j])
31                 closedge[j] = map[pos][j];
32         }
33      }
34 }
35 int main()
36 {
37     while(scanf("%d", &n) != EOF && n)
38     {
39         int i, j;
40         char s, e;
41         int temp, tv, ts, te;
42         sum = 0;
43         memset(map, 127, sizeof(map));
44         for(i = 0; i < n - 1; i++){
45               cin >> s >> temp;
46               ts = s - 'A' + 1;
47               for(j = 0; j < temp; j++){
48                 cin >> e >> tv;
49                 te = e - 'A' + 1;
50                 map[ts][te] = map[te][ts] = tv;
51               }
52         }
53         prim();
54         cout << sum << endl;
55     }
56     return 0;
57 }
posted @ 2012-04-19 19:54  背着超人飞  阅读(152)  评论(0)    收藏  举报