时间:2016-04-13 23:52:36 星期三
题目编号:[2016-04-13][POJ][2349][Arctic Network]
题目大意:问最小生成树中,第k大的边是多少
分析:直接kruskal,合并到倒数第k条边即可
遇到的问题:POJ 输出用 %f 而不是 %lf
#include<cstdio>#include<set>#include<cmath>#include<algorithm>using namespace std;const int maxn = 500 + 10;int fa[maxn];void ini(int n){ for(int i = 0 ; i <= n ; ++i) fa[i] = i;}int fnd(int x){ return x == fa[x] ? x : fa[x] = fnd(fa[x]);}struct Point{ int x,y;}pp[maxn];struct Edge{ int u,v,c; Edge(int a=0,int b=0,int cc=0):u(a),v(b),c(cc){} bool operator < (const Edge & a)const{ return c < a.c; } }e[maxn * maxn];int dis(int a,int b){ return (pp[a].x - pp[b].x)*(pp[a].x - pp[b].x) + (pp[a].y - pp[b].y)*(pp[a].y - pp[b].y);}int main(){ int t; scanf("%d",&t); while(t--){ int s,p; scanf("%d%d",&s,&p); for(int i = 0 ; i < p;++i){ scanf("%d%d",&pp[i].x,&pp[i].y); } ini(p); int cnt = 0; for(int i = 0 ; i < p; ++i){ for(int j = 0; j < p ; ++j){ e[cnt++] = Edge(i,j,dis(i,j)); } } sort(e,e+cnt); int k = 0,ans = 0; for(int i = 0 ; i < cnt; ++i){ int f1 = fnd(e[i].u); int f2 = fnd(e[i].v); if(f1 != f2){ fa[f1] = f2; ++k; if(k == p - s){ ans = e[i].c; break; } } if(k == p - 1) break; } printf("%.2f\n",sqrt(double(ans))); } return 0;}