HDOJ-1875-畅通工程再续 解题报告
来源:互联网 发布:网络音视频许可证 编辑:程序博客网 时间:2024/05/20 21:47
一道最小生成树题目。题意为中文描述不多说。比起一般的最小生成树题目来说,本题需要考虑浮点数的比较,另外对边长也有限制(如题目所说:两岛之间的距离不能小于10米也不能大于1000米),也就是说在此情况下不能直接将两小岛连通。
我的解题思路:首先计算和比较浮点数的大小要尤其注意,其次根据题意,两岛之间的距离不满足题目要求的视做无法直接连通。注意这两点之后用kruskal算法或者prim算法解决就可以了。
下面是解题代码:kruskal解法
#include <stdio.h>#include <stdlib.h>#include <math.h>#define N 105typedef struct side //定义边结构体{ int a, b; //两点(岛)的下标 double len; //边长(距离)}side;typedef struct point //定义点结构体{ int x, y; //坐标}point;point p[N];side s[N*N];int bleg[N]; //并查集使用,存储父节点int pn; //点的数量int sn; //边的数量int t; //测试样例数void Init(); //初始化void Read(); //输入double Count(int i, int j); //计算边长void Kruskal();int Mycmp(const void *a, const void *b); //qsort比较函数int Find(int x); //并查集查找void Union(int x, int y); //并查集合并int Test(); //检测工程是否畅通int main(){ scanf("%d", &t); while (t--) { Init(); Read(); Kruskal(); } return 0;}void Init() //初始化{ int i; for (i=0; i<N; ++i) { bleg[i] = i; } sn = pn = 0; return;}void Read() //输入{ int i, j; scanf("%d", &pn); for (i=0; i<pn; ++i) { scanf("%d %d", &p[i].x, &p[i].y); for (j=0; j<i; ++j) //开始计算新增的边 { s[sn].a = i; s[sn].b = j; s[sn++].len = Count(i, j); } } return;}double Count(int i, int j) //计算边长{ double dx = ((double)p[i].x - p[j].x) * (p[i].x - p[j].x); double dy = ((double)p[i].y - p[j].y) * (p[i].y - p[j].y); return sqrt(dx + dy);}void Kruskal(){ int i; double ans = 0; qsort(s, sn, sizeof(side), Mycmp); for (i=0; i<sn; ++i) //忽略边长小于10的边 { if (s[i].len >= 10) break; } for (; i<sn; ++i) { if (s[i].len <= 1000 && Find(s[i].a) != Find(s[i].b)) //要求边长小于等于1000 { ans += s[i].len; Union(s[i].a, s[i].b); } } if (Test() == 1) { printf("%.1f\n", 100 * ans); } else { printf("oh!\n"); } return;}int Mycmp(const void *a, const void *b) //qsort比较函数{ if ((*(side *)a).len > (*(side *)b).len) { return 1; } return -1;}int Find(int x) //并查集查找{ int y = bleg[x]; int z; while (y != bleg[y]) { y = bleg[y]; } while (x != bleg[x]) { z = bleg[x]; bleg[x] = y; x = z; } return y;}void Union(int x, int y) //并查集合并{ int fx = Find(x); int fy = Find(y); bleg[fx] = fy; return;}int Test() //检测工程是否畅通{ int i; int x = bleg[0]; for (i=1; i<pn; ++i) { if (bleg[i] != x) //出现有两小岛不属于同一个集合时说明工程未畅通 { return 0; } } return 1;}
0 0
- HDOJ-1875-畅通工程再续 解题报告
- HDOJ 1232 畅通工程解题报告
- hdu 1875 畅通工程再续 解题报告
- 解题报告:{HDU}{1874}{畅通工程续}
- HDU1874 畅通工程续 解题报告--Dijkstra
- HDOJ 1875 畅通工程再续
- HDOJ 1875 畅通工程再续
- HDOJ 1875 畅通工程再续
- ACM HDOJ 1875 (畅通工程再续)
- hdoj-1875-畅通工程再续
- HDOJ 1875 畅通工程再续
- HDOJ 畅通工程再续 1875
- HDOJ--1875--畅通工程再续
- hdoj 1875 畅通工程再续
- HDOJ-1875-畅通工程再续
- hdoj 1875 畅通工程再续
- hdoj 1875 畅通工程再续 (prim )
- Hdu1232畅通工程 解题报告
- 20140602今天刚开通博客
- Oracle数据库账号被锁定时解锁方法
- javascript--事件触发
- (难度:35%)untrusted游戏通关攻略
- uva 825 Walking on the Safe Side
- HDOJ-1875-畅通工程再续 解题报告
- IOS学习之基于IOS7的tab bar
- 把一整数转换为字符串
- 07-Java面试题总结
- 为什么在别的主机上调用某个主机写的C#的web service,没有'调用'按钮
- Oanda账户2014重回起点
- Hi3520D SDK 安装以及升级使用说明
- jsoup的基础理论(一)
- POJ 1322 Chocolate