Description
Given n nodes in a two-dimensional space, we want to use single-link custering method to find k clusters. This is equivalent to finding an MST (Minimum spanning tree) of these nodes and deleting k-1 longest edges.
Your job is to output the length of the (k-1)-th longest edges of the MST.
Input
There are multiple cases. For each case, the first line includes n and k (2<=k<=n<=100). The following n lines give the coordinates of n nodes. You may use Euclidean distance to measure the distance between two nodes.
Output
For each case, output the length of the (k-1)-th longest edges. The precision is set to 2 digits after the decimal point.
题目解释:对于n个二维空间点进行聚类,将n个二维空间点分成k类。这道题转化的思想就是,先生成最小生成树,然后删除k-1个最长边
输入:第一行为节点数n以及最终分类的类别数k(2<= k <= 100),后面n行,每一行包括两个数表示二维空间的点
输出:第k-1长的边的长度
#include <iostream> #include <math.h> #include <vector> #include <iomanip> using namespace std; struct minNode { int index; float value; }; struct Point { int x,y; }; //Calculate the Euclidiean distance between two nodes float CalDistance(Point a, Point b) { return sqrt((a.x - b.x)*(a.x - b.x) + (a.y - b.y)*(a.y - b.y)); } float maxEdge(float *graph, int n) { float maxLen = graph[0]; for(int i=1;i<n;i++) { if(graph[i]>=maxLen) maxLen = graph[i]; } return maxLen; } // 距i点最小距离的点 int minIndex(int i, float* graph, int n, bool *flag) { float maxLen = maxEdge(graph, n); int j=0; for(int k=0;k<n;k++) { if(k==i || flag[k]==true) continue; if(graph[k] <= maxLen) { maxLen = graph[k]; j=k; } } return j; } int main(int argc, const char * argv[]) { int n,k,i,j; while(cin >> n >> k) { vector<Point> Coordinate; for( i = 0; i < n; i++) { Point tmp; cin >> tmp.x >> tmp.y; Coordinate.push_back(tmp); } //开始求出图 float graph[n][n]; for(i = 0; i < n; i++) { for(j = 0; j <= i; j++) { graph[i][j] = graph[j][i] = CalDistance(Coordinate[i], Coordinate[j]); } } bool flag[n]; for(i=0;i<n;i++) { flag[i] = false; } vector<float> edges; flag[0] = true; for(i=0;i<n-1;i++) { vector<minNode> minedges; for(int j=0;j<n;j++) { if(flag[j]) { int a = minIndex(j, graph[j], n, flag); minNode node; node.value = graph[j][a]; node.index = a; minedges.push_back(node); } } //找出最小边 minNode minnode = minedges[0]; for(int j=1;j<minedges.size();j++) { if(minedges[j].value < minnode.value) minnode = minedges[j]; } edges.push_back(minnode.value); flag[minnode.index] = true; } //排序 for(i =0; i< n-1; i++) { for(j =i+1; j< n-1; j++) { if(edges[j] > edges[i]) { float tmpV = edges[j]; edges[j] = edges[i]; edges[i] = tmpV; } } } cout << setiosflags(ios::fixed) << setprecision(2) << edges[k-2] << endl; } return 0; }
实现最小生成树的方法一般包括prim算法和Kruskal算法,这里使用的是prim算法来实现的。
代码新手,欢迎各位大神提出宝贵的意见和建议