题意:求最小生成树,不过可以减少s-1条最大的边。
思路:求出最小生成树所有的边,按升序排好序后输出第s-1大的边。
注意:在poj上用g++交double输出要用%f,不然会错。。。
代码:
#include <iostream>
#include <algorithm>
#include <climits>
#include <cstdio>
#include <cmath>
using namespace std;
const int maxn = 505;
struct point{
double x,y;
};
int s,p;
double edge[maxn][maxn];
point a[maxn];
double lowcost[maxn];
double res[maxn];
double Dis(point &a, point &b){
return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
}
void Init(){
cin>>s>>p;
for(int i = 0;i < p; i++){
cin>>a[i].x>>a[i].y;
}
for(int i = 0; i < p-1; i++){
for(int j = i+1; j < p; j++){
edge[i][j] = edge[j][i] = Dis(a[i],a[j]);
}
}
}
double Prim(int u){
int num = 0;
for(int i = 0; i < p; i++){
lowcost[i] = edge[u][i];
}
lowcost[u] = -1;
for(int i = 0; i < p-1; i++){
int min = INT_MAX;
int v;
for(int j = 0; j < p; j++){
if(lowcost[j] != -1 && lowcost[j] < min){
min = lowcost[j]; v = j;
}
}
res[num++] = lowcost[v];
lowcost[v] = -1;
for(int j = 0; j < p; j++){
if(edge[v][j] < lowcost[j])
lowcost[j] = edge[v][j];
}
}
sort(res,res+num);
return res[num-1-(s-1)];
}
int main(){
int t;
cin>>t;
while(t--){
Init();
printf("%.2lf\n",Prim(0));
}
return 0;
}