畅通工程再续 HDU - 1875

题目链接http://acm.hdu.edu.cn/showproblem.php?pid=1875

题意:

在一个叫“百岛湖”的地方有 n 个小岛,政府决定要通过在岛之间建立桥使得小岛互相联通,但是距离小于10或大于1000的两个岛之间是无法建立桥的,桥的花费按照长度计费。如果能连通,那么输出最小话费,如果不能连通则输出 oh!

思路:

显然是最小生成树了,但是要注意题中给的是各岛的坐标,通过坐标算出岛之间的距离之后还要判断是否小于10或大于1000,如果是,那么两岛间无法建立桥,我们将他们之间的距离置为 INF.然后再 prim 算法中我们还要判断是否在最小生成树的总权值中加入了 n - 1 条边。如果不够我们则要输出 “oh!”,因为这证明该图是不连通的。

代码:

#include <bits/stdc++.h>
#define N 105
#define INF 1e10
#define fp(_p,_q,_r) for(int _p = _q;_p < _r;_p ++)
using namespace std;
int ro,n,co[N][2];
double cost[N][N];
double d[N];
bool used[N];
void prim(){
    fill(d,d + N,INF);
    fill(used,used + N,false);
    d[0] = 0;
    double res = 0;
    fp(j,0,n){
        int v = -1;
        double m = INF;
        fp(i,0,n){
            if(!used[i] && m > d[i]) m = d[v = i];
        }
        if(v == -1){
            printf("oh!\n");
            return ;
        }
        used[v] = 1;
        res += d[v];
        fp(i,0,n) d[i] = min(d[i],cost[v][i]);
    }
    printf("%.1lf\n",100 * res);
}
int main(void)
{
    cin >> ro;
    while(ro --){
        bool ok = true;
        fill(cost[0],cost[0] + N * N,INF);
        scanf("%d",&n);
        fp(i,0,n){
            scanf("%d%d",&co[i][0],&co[i][1]);
            fp(j,0,i){
                cost[i][j] = cost[j][i] = sqrt(pow(co[i][0] - co[j][0],2) + pow(co[i][1]-co[j][1],2));
                if(cost[i][j] < 10 || cost[i][j] > 1000) cost[i][j] = cost[j][i] = INF;
            }
        }
        prim();
    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值