题目链接:
题目大意:
给你一些点的坐标,然后求连通这些点的最小线段的长度。
解题思路:
其实也就是最小生成树的裸题。只不过需要对这n个点全部处理一下,求出每对点之间的长度,然后存入邻接矩阵。然后就KO了。。
这道题悲剧的地方在于最大值赋值的时候出现了错误,在比赛里提交编译错误,在外面提交就AC了。问了N个人也没能解决。
原来是最大值越界了。
以后要用#include<climits>里面的INT_MAX来给变量赋最大值。这样就不会出错了,因为是系统变量。。。。
代码如下:
#include<cstdio> #include<cmath> #include<cstring> #include<climits> //INT_MAX的头文件 #include<algorithm> using namespace std; #define MAXN 110 double map[MAXN][MAXN], lowcost[MAXN]; bool visit[MAXN]; double sum; struct point { double x, y; }; point dian[MAXN]; double fun(const point x, const point y) { return sqrt((y.y - x.y) * (y.y - x.y) + (y.x - x.x) * (y.x - x.x)); } void prim(int end) { double temp; int i, j, k; sum = 0; memset(visit, false, sizeof(visit)); for(i = 1; i <= end; ++i) lowcost[i] = map[1][i]; visit[1] = true; for(i = 1; i <= end; ++i) { temp =INT_MAX; //这里错了N久。。以后就这么用了。。。 for(j = 1; j <= end; ++j) if(!visit[j] && temp > lowcost[j]) temp = lowcost[k = j]; if(temp == INT_MAX) break; visit[k] = true; sum += temp; for(j = 1; j <= end; ++j) if(!visit[j] && lowcost[j] > map[k][j]) lowcost[j] = map[k][j]; } } int main() { int i, j, num, count; double x, y; while(scanf("%d", &num) != EOF) { count = 0; for(i = 1; i < MAXN; ++i) for(j = 1; j < MAXN; ++j) map[i][j] = INT_MAX; for(i = 1; i <= num; ++i) { count++; scanf("%lf%lf", &dian[count].x, &dian[count].y); } for(i = 1; i <= count; ++i) for(j = 1; j <= count; ++j) { if(j == i) continue; map[i][j] = min(map[i][j], fun(dian[i], dian[j])); } prim(count); printf("%.2lf\n", sum); } return 0; }