这道题我至少得提交了十几遍,一直WA,最后实在没办法了,看了一下大神们的代码,明白了POJ不能用.2lf,只能用.2f 。。。。。。学到了学到了
思路大体就是先求出最小生成树,然后将这些边的权排序,第n大的边即所求
AC代码:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#define inf 0x3f3f3f3f
using namespace std;
double map[510][510];
int vis[510],adj[510];
double dis[510],sum[510];
int n,m,cnt;
double cmp(double x,double y)
{
return x>y;
}
struct node{
int x;
int y;
};
node a[510];
void prim()
{
cnt=1;
int i,j,k;
memset(vis,0,sizeof(vis));
memset(sum,0.0,sizeof(sum));
for(i=1;i<=m;i++)
{
dis[i]=map[1][i];
adj[i]=1; //求坐标的时候可能用到这个数组,此题无用!
}
dis[1]=0;
vis[1]=1;
for(i=1;i<m;i++)
{
double minn=10000000;
k=1;
for(j=1;j<=m;j++)
{
if(!vis[j]&&minn>dis[j])
{
minn=dis[j];
k=j;
}
}
vis[k]=1;
sum[cnt]=minn;
cnt++;
for(j=1;j<=m;j++)
{
if(!vis[j]&&dis[j]>map[k][j])
{
dis[j]=map[k][j];
adj[j]=k;
}
}
}
}
int main()
{
int i,j;
int t;
scanf("%d",&t);
while(t--)
{
memset(map,0.0,sizeof(map));
scanf("%d%d",&n,&m);
for(i=1;i<=m;i++)
{
scanf("%d%d",&a[i].x,&a[i].y);
}
for(i=1;i<=m;i++)
{
for(j=i+1;j<=m;j++)
{
map[i][j]=map[j][i]=(double)sqrt((a[i].x-a[j].x)*(a[i].x-a[j].x)+(a[i].y-a[j].y)*(a[i].y-a[j].y));
}
}
prim();
sort(sum+1,sum+1+cnt,cmp);
double x=sum[n];
printf("%.2f\n",x);
}
return 0;
}