卧薪尝胆,厚积薄发。
      
    
            JSOI2010 部落划分
        
        
        Description:
将一些点划分成
$k$
部分,使得各部分之间最近的两个点最远。
$1\le n \le 1000$
Solution:
处理出各个点之间的距离
$kruskal$
合并即可。
Code:
#include<algorithm>
#include<iostream>
#include<cstdlib>
#include<cstdio>
#include<cmath>
#include<cstring>
using namespace std;
int n,k;
#define MAXN 1010
double x[MAXN],y[MAXN];
struct edge
{
    int u,v;
    double d;
}e[MAXN * MAXN];
int edgenum = 0;
inline void add(int a,int b,double c){++edgenum;e[edgenum].u = a;e[edgenum].v = b;e[edgenum].d = c;return;}
inline double dis(int a,int b){return sqrt((x[a] - x[b]) * (x[a] - x[b]) + (y[a] - y[b]) * (y[a] - y[b]));}
int f[MAXN];
int find(int x){return (x == f[x] ? x : f[x] = find(f[x]));}
bool cmp(edge a,edge b){return a.d < b.d;}
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)
        {
            add(i,j,dis(i,j));
        }
    }
    for(int i = 1;i <= n;++i)
    {
        f[i] = i;
    }
    int siz = n;
    sort(e + 1,e + 1 + edgenum,cmp);
    int i;
    for(i = 1;i <= edgenum && siz != k;++i)
    {
        if(find(e[i].u) == find(e[i].v))continue;
        f[find(e[i].u)] = find(e[i].v);
        --siz;
    }
    while(find(e[i].u) == find(e[i].v))++i;
    printf("%.2f\n",e[i].d);
    return 0;
}
 In tag:
图论-kruskal
          In tag:
图论-kruskal 
          
        
        Copyright © 2020
        
          wjh15101051
        
      
      ღゝ◡╹)ノ♡
     Date: Wed Aug 01 15:26:09 CST 2018
          Date: Wed Aug 01 15:26:09 CST 2018
           In Category:
          In Category:
           
         Timeline
            Timeline
           About
            About
           Toolbox
            Toolbox
           Friends
              Friends