您的位置:首页 > 其它

HDU 1875 畅通工程再续 最小生成树问题

2013-07-30 20:01 453 查看
题目描述:输入一个T,表示有T组测试数据,然后每组测试数据有一个C,表示在一个湖里面有C座岛屿,现在要在岛屿之间修建桥,可以修建必须满足的条件是岛与岛之间的距离在10到1000的范围内,然后给出每座岛屿的坐标,并且每米的修建桥的费用为100,求能把所有岛屿连接起来的所需要的最小费用,如果不能将所有的岛屿联通,则输出oh?

解题报告:比较裸的一道最小生成树,因为有一个判断到底是否存在最小生成树的问题,所以,个人觉得用克鲁斯卡尔比较好,因为要用到并查集,那样就不用再另外写一个并查集了。直接看代码:

#include<cstdio>
#include<algorithm>
#include<cmath>
const int MAX = 100+5;
double map[MAX][MAX],loc[MAX][2];
struct node {
int x,y;
double length;
}rode[MAX];
bool cmp(node a,node b) {    //比较函数
return a.length<b.length;
}
int T,C,prim[MAX];
double distan(double x1,double y1,double x2,double y2) { //求两岛屿之间的距离
return sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));
}
int find(int k) {   //并查集
return prim[k]==k? k:prim[k] = find(prim[k]);
}
int main() {
scanf("%d",&T);
while(T--) {
scanf("%d",&C);
for(int i = 1;i<=C;++i)
scanf("%lf%lf",&loc[i][0],&loc[i][1]);
int k = 0;
for(int i = 1;i<=C;++i)
for(int j = i+1;j<=C;++j) {   //将距离转换成边
double dis = distan(loc[i][0],loc[i][1],loc[j][0],loc[j][1]);
if(dis<=1000&&dis>=10)
rode[++k].x = i,rode[k].y = j,rode[k].length = dis;
}
std::sort(rode+1,rode+k+1,cmp);
double sum = 0;
for(int i = 1;i<=C;++i)
prim[i] = i;
for(int i = 1;i<=k;++i)
if(find(rode[i].x)!=find(rode[i].y)) {
prim[find(rode[i].x)] = find(rode[i].y);
sum+=rode[i].length;
}
bool flag = 0;
for(int i = 2;i<=C;++i) //判断是否存在最小生成树
if(find(1)!=find(i)) {
flag = 1;
break;
}
if(flag) {
printf("oh!\n");
continue;
}
printf("%.1lf\n",100.0*sum);
}
return 0;
}


View Code
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: