1 solutions

  • 0
    @ 2024-1-5 10:30:02

    题意:有n个点,有k个集合。问你怎么分,集合与集合之间的距离是集合内最近两个点的距离,问你怎么分才能使靠得最近的两个集合距离最大。

    分析:最小生成树问题,一共有k棵树,每个点之间都有一个距离,也就是有一条边。n^2的复杂度求出每一个边,然后套模板。

    code:

    #include<bits/stdc++.h>
    using namespace std;
    const int N=1e6+12;
    int n,k,cnt;
    int fa[10012];
    int f(int x)
    {
      if( fa[x]==x ) return x;
      return fa[x]=f(fa[x]);
    }
    struct node{
      int a,b;
      double w;
      bool operator <(const node &other)
      {
        return w<other.w;
      }
    }g[N];
    struct point{
      double x,y;
    }p[10012];
    double dis(point a,point b)
    {
      return sqrt( (a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y) );
    }
    void kruskal(){
      int sum=0;
      for(int i=1;i<=cnt;i++)
      {
        int a=f(g[i].a),b=f(g[i].b);
        if( a==b ) continue;
        if( sum>=n-k  ) {
        printf("%.2lf",g[i].w);
        break;
        }
        sum++;
        fa[a]=b;
        cnt++;
      }
    
    
    }
    int main(){
      cin>>n>>k;
      for(int i=1;i<=n;i++)
      {
        fa[i]=i;
        cin>>p[i].x>>p[i].y;
      }
      for(int i=1;i<=n;i++)
      {
        for(int j=i+1;j<=n;j++)
        {
              ++cnt;
              g[cnt].a=i,g[cnt].b=j;
              g[cnt].w=dis( p[i],p[j] );
        }
      }
      //cout<<cnt<<endl;
      sort( g+1,g+1+cnt );
      kruskal();
    }
    
    • 1

    Information

    ID
    10478
    Time
    1000ms
    Memory
    256MiB
    Difficulty
    10
    Tags
    # Submissions
    2
    Accepted
    2
    Uploaded By