最小生成树+并查集:洛谷P4047 [JSOI2010]部落划分

原题传送门

把所有两点之间的边存入priority_queue中(priority_queue重载运算符<然后用node),一开始每个点单独一个集合,不断合并不在同一集合内的距离最近的点,直到剩余m个集合

重点:priority_queue的使用

#include<bits/stdc++.h>
#define INF 2147483647
using namespace std;
int dad[5003];
struct node{
    int num,to;
    double value;
};
int find(int x){
    if(dad[x]==x) return x;
    dad[x]=find(dad[x]);
    return dad[x];
}
bool operator < (const node &a, const node &b){
    return a.value > b.value;
} 
int main(){
    vector<node>a[5003];
    int ax[1003],ay[1003];
    priority_queue<node> q;
    int n,m,i,x,y,z,ans,ansn;
    node t;t.value=INF;
    memset(dad,0,sizeof(dad));
    cin>>n>>m;
    for(i=1;i<=n;i++){
        dad[i]=i;
        scanf("%d%d",&ax[i],&ay[i]);
        for(int j=1;j<i;j++){
            node b;
            b.num=i;b.to=j;b.value=(ax[i]-ax[j])*(ax[i]-ax[j])+(ay[i]-ay[j])*(ay[i]-ay[j]);
            q.push(b);
        }
    }
    ans=n;ansn=0;node b;
    while(ans>=m){
        b=q.top();q.pop();x=b.to;
        if(find(x)==find(b.num)) continue;
        dad[find(x)]=b.num;ans--;
//        printf("%d->%d:%d\n",b.num,b.to,b.value);
    }
    printf("%.2lf",sqrt(b.value));
} 

 

posted @ 2021-11-06 18:38  遥望未来weilai  阅读(35)  评论(0编辑  收藏  举报