有n个点,给出坐标,把它们全部连接起来最少要多少钱,1m的桥100块,如果它们之间的距离大于1000或者小于10就不能连接
求出距离,距离小于10或者大于1000的设置为inf,而不是在后面去判断是否符合条件,这样可能会有奇奇怪怪的东西出现,导致wa
直接上prim就行
#include<iostream>
#include<string>
#include<cstring>
#include<cmath>
#include<vector>
#include<climits>
#include<cstdio>
#include<queue>
#include<algorithm>
#include<cfloat>
using namespace std;
const double inf=DBL_MAX;
double mat[205][205],xy[205][2];
int N;
struct island
{
bool vis;
double dis;
};
island edge[205];//辅助数组
double distance(double x1,double y1,double x2,double y2)
{
double ans,t1,t2;
t1=(x2-x1)*(x2-x1);
t2=(y2-y1)*(y2-y1);
t1+=t2;
ans=sqrt(t1);
return ans;
}//计算两点之间的距离
int getmin()
{
int i,j,index=-1;
double MIN=inf;
for(i=1;i<=N;i++)
{
if(MIN>edge[i].dis&&!edge[i].vis)
{
MIN=edge[i].dis;
index=i;
}
}
return index;
}//找出离最小生成树最短的点
double prim()
{
int i,j,cnt,k;
double sum=0;
edge[1].dis=0;
edge[1].vis=1;
for(i=2;i<=N;i++)
{
edge[i].vis=0;
edge[i].dis=mat[1][i];
}
cnt=1;//计算当前有多少个点加入了生成树
while(1)
{
k=getmin();
if(k==-1)break;//找不到点了
edge[k].vis=1;
sum+=edge[k].dis;
for(i=1;i<=N;i++)
{
if(edge[i].vis==0&&edge[i].dis>mat[k][i])
{
edge[i].dis=mat[k][i];
}
}//更新最短距离
cnt++;
if(cnt==N)break;//已经找完了
}
if(cnt==N)return sum;
else return -1;
}
int main()
{
int T,i,j;
double temp,ans;
scanf("%d",&T);
while(T--)
{
scanf("%d",&N);
for(i=1;i<=N;i++)
{
scanf("%lf%lf",&xy[i][0],&xy[i][1]);
}
for(i=1;i<=N;i++)
{
for(j=1;j<=i;j++)
{
temp=distance(xy[i][0],xy[i][1],xy[j][0],xy[j][1]);
if(temp<10||temp>1000)
//如果不设置为inf,而是在其他地方再判断就wa了,很奇怪
temp=inf;
mat[i][j]=mat[j][i]=temp;
}
}
ans=prim();
if(ans==-1)printf("oh!\n");
else printf("%.1lf\n",ans*100);
}
return 0;
}