最小生成树+并查集:洛谷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)); }