Sicily Single-link Clustering| Prim算法

来源:互联网 发布:淘宝千里眼插件免费的 编辑:程序博客网 时间:2024/06/01 10:40

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]);    }}
0 0
原创粉丝点击