• ZOJ 1203 Swordfish(最小生成树Prim)


    复习。 

    借图= = 

    n个点,给出两两点之间的距离,求最小生成树的边长度之和。

    稠密图,用prim。

     1 #include <iostream>
     2 #include <cmath>
     3 #include <cstring>
     4 #include <iomanip>
     5 using namespace std;
     6 
     7 const double maxd = 1000001;
     8 const int N = 105;
     9 
    10 double x[N], y[N];
    11 double map1[N][N], dis[N];
    12 int vis[N];
    13 
    14 double cal(int i, int j)
    15 {
    16     double ret = (y[i] - y[j]) * (y[i] - y[j]) + (x[i] - x[j]) * (x[i] - x[j]);
    17     return sqrt(ret);
    18 }
    19 
    20 void input(int n)
    21 {
    22     for(int i=1; i<=n; i++)
    23         cin >> x[i] >> y[i];
    24     for(int i=1; i<=n; i++)
    25     {
    26         map1[i][i] = maxd;
    27         for(int j=i+1; j<=n; j++)
    28             map1[i][j] = map1[j][i] = cal(i,j);
    29     }
    30 }
    31 
    32 /*
    33  *代码思路:已一个点为起点,找n-1次,每次添加一个点进入结果集
    34  *dis[i]维护结果集与i点的最短距离
    35  *vis[i]代表点i是否已加入结果集
    36  *
    37  */
    38 double prim(int n)
    39 {
    40     double ret = 0;
    41     int cur = 1;
    42     for(int i=1; i<=n; i++) dis[i] = maxd;
    43     memset(vis, 0sizeof(vis));
    44     dis[cur] = 0; vis[cur] = 1;
    45     //找n-1轮
    46     for(int i=1; i<n; i++)
    47     {
    48         //枚举上一次加入的点与各个点的距离,更新最小距离dis[i]
    49         for(int j=1; j<=n; j++)
    50         {
    51             if(vis[j]==0 && dis[j]>map1[cur][j])
    52                 dis[j] = map1[cur][j];
    53         }
    54         //选出最短的边,把该边连接的点加入结果集
    55         double mind = maxd;
    56         for(int j=1; j<=n; j++)
    57         {
    58             if(vis[j]==0 && dis[j]<mind)
    59             {
    60                 mind = dis[j];
    61                 cur = j;
    62             }
    63         }
    64         vis[cur] = 1;
    65         ret += mind;
    66         //cout << i << ": " << mind << endl;
    67     }
    68     return ret;
    69 }
    70 
    71 int main()
    72 {
    73     int Case = 1, n;
    74     while(cin >> n)
    75     {
    76         if(n==0break;
    77         input(n);
    78         double ans = prim(n);
    79 
    80         if(Case>1) cout << endl;
    81         cout << "Case #" << Case++ << ":" << endl;
    82         cout << "The minimal distance is: ";
    83         cout << setiosflags(ios::fixed) << setprecision(2) << ans << endl;
    84     }
    85     return 0;
    86 }
    View Code 

    注意算法思想与代码思路。。 

  • 相关阅读:
    F. 数学上来先打表
    LibreOJ β Round #2
    noip飞扬的小鸟
    jxoi2017
    分块算法
    Chino的数列
    cf 613E
    cf 126D
    cf 542E
    cf 512D
  • 原文地址:https://www.cnblogs.com/byluoluo/p/3454317.html
Copyright © 2020-2023  润新知