• poj1251 Jungle Roads(Prime || Kruskal)


    题目链接

    http://poj.org/problem?id=1251

    题意

    有n个村庄,村庄之间有道路连接,求一条最短的路径能够连接起所有村庄,输出这条最短路径的长度。

    思路

    最小生成树问题,使用普利姆算法(Prime)或者克鲁斯卡尔算法(Kruskal)解决。

    代码

    Prime算法:

     1 #include <algorithm>
     2 #include <iostream>
     3 #include <cstring>
     4 #include <cstdio>
     5 using namespace std;
     6 
     7 const int INF = 0xfffffff;
     8 const int N = 30;
     9 int n;
    10 int jungle[N][N];
    11 int dist[N];    //记录从起点到其余各点的距离并不断更新
    12 
    13 int prime()
    14 {
    15     int min_edge, min_node;
    16     for (int i = 0; i < n; i++)
    17         dist[i] = INF;
    18     int now = 0;
    19     int ans = 0;
    20     for (int i = 0; i < n - 1; i++)
    21     {
    22         dist[now] = -1;    //标记结点now+'A'被访问过了
    23         min_edge = INF;
    24         for (int j = 0; j < n; j++)
    25         {
    26             if (j != now && dist[j]>=0)
    27             {
    28                 if (jungle[now][j]>0)
    29                     dist[j] = min(dist[j], jungle[now][j]);
    30                 if (dist[j] < min_edge)
    31                 {
    32                     min_edge = dist[j];    //选取从当前结点到其余各点的最短路径
    33                     min_node = j;
    34                 }
    35             }
    36         }
    37         now = min_node;
    38         ans += min_edge;    //当前最小生成树的长度
    39     }
    40     return ans;
    41 }
    42 
    43 int main()
    44 {
    45     //freopen("poj1251.txt", "r", stdin);
    46     while (cin >> n && n)
    47     {
    48         memset(jungle, 0, sizeof(jungle));
    49         for (int i = 0;i < n-1;i++)
    50         {
    51             char p, q;
    52             int v, w;
    53             cin >> p >> v;
    54             for (int j = 0;j < v;j++)
    55             {
    56                 cin >> q >> w;
    57                 jungle[p - 'A'][q - 'A'] = w;
    58                 jungle[q - 'A'][p - 'A'] = w;
    59             }
    60         }
    61         int ans = prime();
    62         cout << ans << endl;
    63     }
    64     return 0;
    65 }

    Kruskal算法:

     1 #include <algorithm>
     2 #include <iostream>
     3 #include <cstring>
     4 #include <cstdio>
     5 using namespace std;
     6 
     7 const int N = 100;
     8 int s[N], e[N], v[N];    //分别存储每一条路的起点、终点、长度
     9 int p[N];    //并查集使用
    10 int n;
    11 int cnt;    //存储有多少条路
    12 
    13 bool cmp(int i, int j)
    14 {
    15     return v[i] < v[j];
    16 }
    17 
    18 int find_root(int x)
    19 {
    20     if (p[x] == -1)
    21         return x;
    22     else return find_root(p[x]);
    23 }
    24 
    25 int kruskal()
    26 {
    27     memset(p, -1, sizeof(p));
    28     int r[N];
    29     for (int i = 0; i < cnt; i++)
    30         r[i] = i;
    31     sort(r, r + cnt, cmp);    //根据路径长度v[]的大小对数组r[]排序
    32     int ans = 0;
    33     for (int i = 0; i < cnt; i++)
    34     {
    35         int cur = r[i];
    36         int a = find_root(s[cur]);
    37         int b = find_root(e[cur]);
    38         if (a != b)
    39         {
    40             ans += v[cur];
    41             p[a] = b;
    42         }
    43     }
    44     return ans;
    45 }
    46 
    47 int main()
    48 {
    49     //freopen("poj1251.txt", "r", stdin);
    50     while (cin >> n && n)
    51     {
    52         cnt = 0;
    53         char p, q;
    54         int nums, w;
    55         for (int i = 0; i < n - 1; i++)
    56         {
    57             cin >> p >> nums;
    58             for (int j = 0; j < nums; j++)
    59             {
    60                 cin >> q >> w;
    61                 s[cnt] = p - 'A';
    62                 e[cnt] = q - 'A';
    63                 v[cnt] = w;
    64                 cnt++;
    65             }
    66         }
    67         int ans = kruskal();
    68         cout << ans << endl;
    69     }
    70     return 0;
    71 }
  • 相关阅读:
    win10笔记本实现双屏显示的自如切换
    word-如何将文字设置为插入超链接
    opencv-python教程学习系列13-图像平滑
    第12课 经典问题解析一
    第11课 新型的类型转换
    第10课 C++中的新成员
    第9课 函数重载分析(下)
    第8课 函数重载分析(上)
    第7课 函数参数的扩展
    第6课 内联函数分析
  • 原文地址:https://www.cnblogs.com/sench/p/7965658.html
Copyright © 2020-2023  润新知