luogu 4047 [JSOI2010]部落划分 最小生成树

最小生成树或者二分都行,但是最小生成树会好写一些~

Code: 

#include <bits/stdc++.h> 
#define ll long long   
#define N 1000005 
#define setIO(s) freopen(s".in","r",stdin) 
using namespace std;     
ll x[N],y[N]; 
int p[N]; 
struct Edge
{ 
    int u,v; 
    ll c;   
}e[N];     
bool cmp(Edge a,Edge b) 
{
    return a.c<b.c;     
}  
int find(int x) 
{
    return p[x]==x?x:p[x]=find(p[x]);     
}
int main() 
{ 
    // setIO("input");  
    int n,k,i,j,cnt=0,jj;  
    scanf("%d%d",&n,&k); 
    for(i=1;i<=n;++i) scanf("%lld%lld",&x[i],&y[i]);     
    for(i=1;i<=n;++i) p[i]=i;  
    for(i=1;i<=n;++i) 
    {
        for(j=i+1;j<=n;++j) 
        {
            ++cnt;   
            e[cnt].u=i; 
            e[cnt].v=j;      
            e[cnt].c=(x[i]-x[j])*(x[i]-x[j])+(y[i]-y[j])*(y[i]-y[j]);   
        }
    } 
    sort(e+1,e+1+cnt,cmp); 
    ll lst=0;     
    int pp=n; 
    lst=e[1].c;      
    for(i=1;i<=cnt;i=j) 
    {              
        for(j=i;j<=cnt&&e[j].c==e[i].c;++j);    
        for(jj=i;jj<j;++jj) 
        { 
            int u=e[jj].u; 
            int v=e[jj].v;   
            u=find(u), v=find(v); 
            if(u!=v) p[u]=v, --pp;    
            // printf("%d %d %lld\n",e[jj].u,e[jj].v,e[jj].c); 
        }
        if(pp>=k) 
        {
            lst=max(lst,e[j].c); 
        }
        else 
        {
            break; 
        }
    }   
    // printf("%lld\n",lst); 
    printf("%.2f\n",sqrt(lst));     
    return 0; 
}

  

猜你喜欢

转载自www.cnblogs.com/guangheli/p/11602806.html