Sicily Single-link Clustering| Prim算法

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 
#include 
#include 
#include 
#include 
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;icin>>P[i].x>>P[i].y;
        }

        //得到图
        for(int i=0;i0;
            for(int j=i+1;jsqrt((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;ifalse;
            adjvex[i]=0;
            lowcost[i]=G[0][i];
        }

        vis[0]=true;//设0为起点

        std::vector<double> vet;
        for(int i=1;i//对于剩下的n-1个点
        {
            double min=inf;
            int v=-1;
            for(int j=1;j//找到未访问的且距离已访问点集合最小的点
            {
                if(!vis[j]&&lowcost[j]if(v!=-1)
            {
                vis[v]=true;
                vet.push_back(lowcost[v]);

                for(int j=1;j//更新离顶点最近的点和最小距离
                {
                    if(!vis[j]&&G[v][j]//对树中的所有边从大到小排序,找到第k-1条最长的边 
        sort(vet.begin(),vet.end(),greater<double>() );
        printf("%.2lf\n",vet[k-2]);
    }
}

你可能感兴趣的:(Oj)