BZOJ1821: [JSOI2010]Group 部落划分 Group(最小生成树)

题意:传送门

题解:使用最小生成树,最后搞搞是最小生成树的第几条边即可。

附上代码:

#include<bits/stdc++.h>
using namespace std;
inline int read()
{
    char ch=getchar();
    int f=1,x=0;
    while(!(ch>='0'&&ch<='9')){if(ch=='-')f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9'){x=x*10+ch-48;ch=getchar();}
    return x*f;
}
const int maxn=1e3+5;
int n,k,x[maxn],y[maxn],f[maxn];
struct edge{int u,v;double w;}edges[maxn*maxn];
int tot;
void add_edges(int u,int v,double w)
{
    edges[tot].u=u;edges[tot].v=v;edges[tot].w=w;tot++;
}
bool cmp(edge a,edge b)
{
    return a.w<b.w;
}
double dis(int a,int b)
{
    return sqrt((x[a]-x[b])*(x[a]-x[b])+(y[a]-y[b])*(y[a]-y[b]));
}
vector<double>v;
int find(int x){return x==f[x]?x:f[x]=find(f[x]);}
void merge(int a,int b)
{
    int x=find(a),y=find(b);
    if(x!=y)f[y]=x;
}
int main()
{
    n=read();k=read();
    for(int i=1;i<=n;i++)f[i]=i;
    for(int i=1;i<=n;i++){
        x[i]=read();y[i]=read();
    }
    for(int i=1;i<=n;i++){
        for(int j=i+1;j<=n;j++){
            add_edges(i,j,dis(i,j));
        }
    }
    sort(edges,edges+tot,cmp);
    for(int i=0;i<tot;i++){
        int a=find(edges[i].u),b=find(edges[i].v);
        if(a!=b){
            merge(a,b);
            v.push_back(edges[i].w);
//            cout<<edges[i].w<<endl;
        }
    }
    printf("%.2f\n",v[n-k]);
    return 0;
}

猜你喜欢

转载自blog.csdn.net/zhouzi2018/article/details/87915264