poj 3625 Building Roads

点击打开链接poj 3625


思路:最小生成树+prim
分析:
         1 由于点有1000,如果要用kruskal的话最少有1000000条边,所以我么选择用prim算法
         2 题目中的点的坐标最大值为10^6,那么如果在平方一下的话会超过int,所以在求两个点之间的距离的时候用在前面乘上一个1.0这样就表示的double从而不会超过int了。
         3 题目中的说了,要用64位的浮点数,所以选择用long double 。输出的时候是“%0.2Lf”。

代码:


#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<cmath>
using namespace std;
#define MAXN 1010

int n , m;
int vis[MAXN];
long double lowcost[MAXN];
long double G[MAXN][MAXN];
struct Point{
    int x;
    int y;
}p[MAXN];

void init(){
    for(int i = 1 ; i <= n; i++){
       for(int j = 1 ; j <= n ; j++){
          long double tmp_x = 1.0*(p[i].x-p[j].x)*(p[i].x-p[j].x);/*这里注意乘上一个1.0*/
          long double tmp_y = 1.0*(p[i].y-p[j].y)*(p[i].y-p[j].y);/*这里注意乘上一个1.0*/
          G[i][j] = sqrt(tmp_x + tmp_y);
       }
    }
}

void prime(){
     int pos;
     long double ans = 0;
     memset(vis , 0 , sizeof(vis));
     vis[1] = 1;
     for(int i = 1 ; i <= n ; i++)
         lowcost[i] = G[1][i];
     for(int i = 1 ; i <= n ; i++){
        pos = -1;
        for(int j = 1 ; j <= n ; j++){
           if(!vis[j] && (pos == -1 || lowcost[j] < lowcost[pos]))
             pos = j;
        }     
        if(pos == -1)
          break;
        ans += lowcost[pos];
        vis[pos] = 1;
        for(int j = 1 ; j <= n ; j++){
           if(!vis[j] && lowcost[j] > G[j][pos])
             lowcost[j] = G[j][pos];
        }
     }
     printf("%0.2Lf\n" , ans);/*注意输出的格式*/
}

int main(){
    int x , y;
    scanf("%d%d" , &n , &m);
    for(int i = 1 ; i <= n ; i++)
       scanf("%d%d" , &p[i].x , &p[i].y);
    init();
    for(int i = 0 ; i < m ; i++){
       scanf("%d%d" , &x , &y);
       G[x][y] = G[y][x] = 0;
    }
    prime();
    return 0;
}


你可能感兴趣的:(poj 3625 Building Roads)