zoukankan      html  css  js  c++  java
  • 洛谷P2872 [USACO07DEC]Building Roads S(最小生成树)

    题目描述

    Farmer John had just acquired several new farms! He wants to connect the farms with roads so that he can travel from any farm to any other farm via a sequence of roads; roads already connect some of the farms.

    Each of the N (1 ≤ N ≤ 1,000) farms (conveniently numbered 1..N) is represented by a position (Xi, Yi) on the plane (0 ≤ Xi ≤ 1,000,000; 0 ≤ Yi ≤ 1,000,000). Given the preexisting M roads (1 ≤ M ≤ 1,000) as pairs of connected farms, help Farmer John determine the smallest length of additional roads he must build to connect all his farms.

    Farmer John最近得到了一些新的农场,他想新修一些道路使得他的所有农场可以经过原有的或是新修的道路互达(也就是说,从任一个农场都可以经过一些首尾相连道路到达剩下的所有农场)。有些农场之间原本就有道路相连。 所有N(1 <= N <= 1,000)个农场(用1..N顺次编号)在地图上都表示为坐标为(X_i, Y_i)的点(0 <= X_i <= 1,000,000;0 <= Y_i <= 1,000,000),两个农场间道路的长度自然就是代表它们的点之间的距离。现在Farmer John也告诉了你农场间原有的M(1 <= M <= 1,000)条路分别连接了哪两个农场,他希望你计算一下,为了使得所有农场连通,他所需建造道路的最小总长是多少。

    输入格式

    * Line 1: Two space-separated integers: N and M

    * Lines 2..N+1: Two space-separated integers: Xi and Yi

    * Lines N+2..N+M+2: Two space-separated integers: i and j, indicating that there is already a road connecting the farm i and farm j.

    • 第1行: 2个用空格隔开的整数:N 和 M

    • 第2..N+1行: 第i+1行为2个用空格隔开的整数:X_i、Y_i

    • 第N+2..N+M+2行: 每行用2个以空格隔开的整数i、j描述了一条已有的道路, 这条道路连接了农场i和农场j

    输出格式

    * Line 1: Smallest length of additional roads required to connect all farms, printed without rounding to two decimal places. Be sure to calculate distances as 64-bit floating point numbers.

    输出使所有农场连通所需建设道路的最小总长,保留2位小数,不必做 任何额外的取整操作。为了避免精度误差,计算农场间距离及答案时 请使用64位实型变量

    输入输出样例

    输入 #1
    4 1
    1 1
    3 1
    2 3
    4 3
    1 4
    输出 #1
    4.00
    模板题。比较巧妙的一点就是,对于已经存在的边,直接令a[x][y] = a[y][x] = 0即可。
    #include <bits/stdc++.h>
    using namespace std;
    double a[1005][1005], d[1005]; 
    bool vis[1005] = { 0 };
    int n, m;
    struct point
    {
        double x;
        double y;
    } p[1005];
    double calc(point a, point b)
    {
        return sqrt((a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y));
    }
    void prim()
    {
        int i, j, y;
        d[1] = 0;
        for(i = 1; i < n; i++)
        {
            int x = 0;
            for(j = 1; j <= n; j++)
            {
                if(!vis[j] && (x == 0 || d[j] < d[x])) x = j;
            }
            vis[x] = 1;
            for(y = 1; y <= n; y++)
            {
                if(!vis[y]) d[y] = min(d[y], a[x][y]);
            } 
        }
        
    }
    int main()
    {
        int i, j;
        for(i = 1; i <= 1000; i++)
        {
            d[i] = 1e18;
        }
        cin >> n >> m;
        for(i = 1; i <= n; i++)
        {
            cin >> p[i].x >> p[i].y;
        }
        for(i = 1; i <= n; i++)
        {
            for(j = 1; j <= i; j++)
            {
                a[i][j] = a[j][i] = calc(p[i], p[j]);
            }
        }
        double ans = 0.0;
        for(i = 1; i <= m; i++)
        {
            int x, y;
            scanf("%d%d", &x, &y);
            a[x][y] = a[y][x] = 0.0;
        }
        prim();
        for(i = 2; i <= n; i++) 
        {
            ans += d[i];
        }
        printf("%.2lf", ans);
        return 0;
    }
  • 相关阅读:
    java中map接口hashMap以及Enty之间的用法和关系
    Collection集合总结,List和set集合的用法,HashSet和LinkedHashSetde用法
    微信小程序开发攻略
    Java闰年的计算,Calendar的用法
    Java计算计算活了多少天
    Java用代码演示String类中的以下方法的用法
    Java判断一个字符串中有多少大写字母、小写字母和数字
    Java将一个字符串的首位改为大写后边改为小写的实现,String
    Java 获取一个字符串中,另一个字符串出现的次数
    linux下重命名文件或文件夹(linux)
  • 原文地址:https://www.cnblogs.com/lipoicyclic/p/13281922.html
Copyright © 2011-2022 走看看