每組數據首先是一個整數C(C <= 100),代表小島的個數,接下來是C組座標,代表每個小島的座標,這些座標都是 0 <= x, y <= 1000的整數。
Output每組輸入數據輸出一行,代表建橋的最小花費,結果保留一位小數。如果無法實現工程以達到全部暢通,輸出”oh!”. Sample Input
2 2 10 10 20 20 3 1 1 2 2 1000 1000Sample Output
1414.2
oh!
這道題用prim和 kruskal都能寫
我選擇prim
這題我認爲麻煩的地方就是輸入的處理 ,本身是一道模板題 但是就是輸入不好處理
看了下,學到了這種存入方式
#include <iostream>
#include <cmath>
using namespace std;
#define max 101
const int intmax=1<<29;
double p[max][max],dist[max],a[max],b[max];
bool flag[max];
int n,v;
void init()
{
double k;
for (int i=0;i<n;i++)
{
for (int j=0;j<n;j++)
{
if (i==j) p[i][j]=intmax;
else
{
k=sqrt(fabs(1.0*(a[j]-a[i])*(a[j]-a[i])+1.0*(b[j]-b[i])*(b[j]-b[i])));
if (k<=1000&&k>=10)
{
p[i][j]=k;
}
else p[i][j]=intmax;
}
}
}
}
double prim()
{
int i,j;
double min,sum=0;;
for ( i=0;i<n;i++)
{
dist[i]=p[v][i];
flag[i]=0;
}
flag[v]=1;
for (i=0;i<n-1;i++)
{
min=intmax;
for (j=0;j<n;j++)
if (!flag[j]&&min>dist[j])
min=dist[v=j];
if (intmax-min<1e-9)
return -1;
sum+=min;
flag[v]=1;
for (j=0;j<n;j++)
if (!flag[j]&&dist[j]>p[v][j])
dist[j]=p[v][j];
}
return sum;
}
int main()
{
int T,i;
double k;
cin>>T;
while (T--)
{
cin>>n;
for (i=0;i<n;i++)
{
scanf("%lf%lf",&a[i],&b[i]);
}
init();
v=0;
k=prim();
if (k<0)
cout<<"oh!"<<endl;
else printf("%.1lf\n",k*100);
}
return 0;
}