Single-link Clustering
Total: 229 Accepted: 90
Time Limit: 1sec Memory Limit:256MB
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.
Sample Input
Copy sample input to clipboard
6 2
1 1
2 1
1 2
3 3
4 2
4 3
Sample Output
2.24
题意:将二维空间的n个点分成k类。方法为:根据这n个点得到最小生成树,然后删除第k-1条最长的边。
输入:先输入n和k,随后输入n个点的x、y轴左标。
输出:第k-1条最长的边的值
解法:使用prim算法得到最小生成树,用一个数组记录树的边,最后对该数组进行排序,输出第k-1个最大的值
Prim算法参考:这里
代码:
#include <iostream>
#include <vector>
#include <algorithm>
#include <cstdio>
#include <cmath>
using namespace std;
const double inf=1000000007;//随便设的大数
struct point
{
double x,y;
};
int main()
{
int n,k;
while(cin>>n>>k)
{
point P[n];
double G[n][n];//储存点之间的距离
bool vis[n];//判断点是否已经访问
double lowcost[n];//起点到其他点的最小距离
int adjvex[n];//到顶点的最近的点
for(int i=0;i<n;i++)
{
cin>>P[i].x>>P[i].y;
}
//得到图
for(int i=0;i<n;i++)
{
G[i][i]=0;
for(int j=i+1;j<n;j++)
{
G[i][j]=G[j][i]=sqrt((P[i].x-P[j].x)*(P[i].x-P[j].x)
+(P[i].y-P[j].y)*(P[i].y-P[j].y));
}
}
//使用prim算法
for(int i=0;i<n;i++)
{
vis[i]=false;
adjvex[i]=0;
lowcost[i]=G[0][i];
}
vis[0]=true;//设0为起点
std::vector<double> vet;
for(int i=1;i<n;i++)//对于剩下的n-1个点
{
double min=inf;
int v=-1;
for(int j=1;j<n;j++)//找到未访问的且距离已访问点集合最小的点
{
if(!vis[j]&&lowcost[j]<min)
{
min=lowcost[j];
v=j;
}
}
if(v!=-1)
{
vis[v]=true;
vet.push_back(lowcost[v]);
for(int j=1;j<n;j++)//更新离顶点最近的点和最小距离
{
if(!vis[j]&&G[v][j]<lowcost[j])
{
lowcost[j]=G[v][j];
adjvex[j]=v;
}
}
}
}
//对树中的所有边从大到小排序,找到第k-1条最长的边
sort(vet.begin(),vet.end(),greater<double>() );
printf("%.2lf\n",vet[k-2]);
}
}