题目:http://acm.hdu.edu.cn/showproblem.php?pid=1875
又是最小生成树。。
一开始错了几次。。。
我以为是当两段路大于1000或者小于10就会不符合要求。。
其实是读错题意了。。当两段路大于1000或者小于10。。只应该把这段路变成死路。
下面是AC代码:
#include<iostream>
#include<cmath>
using namespace std;
#define N 9999999
int n;
double map[101][101];
double mark[101];
int visited[101];
double dit(int x1,int y1,int x2,int y2)
{
return sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));
}
void prim()
{
int i,j,k;
int flag=1;
double sum=0,min;
memset(mark,0,sizeof(mark));
memset(visited,0,sizeof(visited));
k=1; //以1为起始点
visited[1]=1;
for(i=2;i<=n;i++)
mark[i]=map[k][i]; //计算k到各顶点的距离
min=N;
for(i=1;i<=n-1;i++) //做n-1次循环
{
for(j=1;j<=n;j++)
if(mark[j]<min&&!visited[j])
{
min=mark[j];
k=j;
}
if(min==N)
{
flag=0;
break;
}
visited[k]=1;
for(j=1;j<=n;j++)
{
if(mark[j]>map[k][j]&&!visited[j])
mark[j]=map[k][j];
}
sum+=min;
min=N;
}
if(flag)
printf("%.1lf\n",sum*100);
else
printf("oh!\n");
}
int main()
{
int t,i,j;
int x[101],y[101];
int flag;
cin>>t;
while(t--)
{
cin>>n;
for(i=1;i<=n;i++)
cin>>x[i]>>y[i];
memset(map,0,sizeof(map));
for(i=1;i<n;i++)
{
for(j=i+1;j<=n;j++)
{
map[i][j]=map[j][i]=dit(x[i],y[i],x[j],y[j]);
if(map[i][j]>1000||map[i][j]<10)
{
map[i][j]=map[j][i]=N;
}
}
}
prim();
}
return 0;
}
//jack is so indifferen to his appearance that he never has his clothes pressed.