时间: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;
}