zoukankan      html  css  js  c++  java
  • bzoj 1821 部落划分

    评测:http://www.lydsy.com/JudgeOnline/problem.php?id=1821
    这里写图片描述
    分析一下题目:
    因为最后答案是距离最近的部落的距离最远,即尽量把短的边合并进部落中。
    一开始可以看做n个部落,将边排一遍序,用克鲁斯卡尔从最小的边开始将两端的点合并(如果不在一个集合中),每合并一次,集合数目就 -1,直到剩下k个部落,那么下一条两端没有在一个集合中的边就是要求的答案。
    和口袋(云彩)的天空(洛谷上的)那个题差不多。

    #include<iostream>
    #include<cstring>
    #include<string>
    #include<algorithm>
    #include<queue>
    #include<cstdio>
    #include<cmath>
    #define P(x) (x)*(x) 
    using namespace std;
    int n,k;
    struct H{
        int x,y;double len;
    }a[600009];int cnt;
    double X[1009],Y[1009];
    int f[1009];
    bool cmp(H p,H q){return p.len<q.len;}
    int find(int x)
    {
        if(x==f[x]) return f[x];
        return f[x]=find(f[x]);
    }
    int main()
    {
        scanf("%d%d",&n,&k);
        for(int i=1;i<=n;i++) scanf("%lf%lf",&X[i],&Y[i]);
        for(int i=1;i<=n;i++) for(int j=i+1;j<=n;j++) 
        a[++cnt].x=i,a[cnt].y=j,a[cnt].len=sqrt(P(X[i]-X[j])+P(Y[i]-Y[j]));
        sort(a+1,a+cnt+1,cmp);
        for(int i=1;i<=n;i++) f[i]=i;
        int p=0;
        while(n>k)
        {
            p++;
            int u=find(a[p].x),v=find(a[p].y);
            if(u!=v) f[u]=v,n--;    
        }
        while(p<=cnt)
        {
            p++;
            int u=find(a[p].x),v=find(a[p].y);
            if(u!=v){printf("%.2lf",a[p].len);return 0;} 
        } 
        return 0;       
    } 
  • 相关阅读:
    奇怪的人
    假象世界
    心态记录
    民用自组织网络公司概要
    禁止VMware虚拟机与Host的时间同步
    20万左右SUV介绍
    手机GPS为什么能在室内定位?
    取余与位运算
    shell 基础进阶 *金字塔
    shell 、awk两种方法编写9*9法表
  • 原文地址:https://www.cnblogs.com/dfsac/p/7587890.html
Copyright © 2011-2022 走看看