1. 程式人生 > 其它 >最小生成樹+並查集:洛谷P4047 [JSOI2010]部落劃分

最小生成樹+並查集:洛谷P4047 [JSOI2010]部落劃分

https://www.luogu.com.cn/problem/P4047

把所有兩點之間的邊存入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)); }