Description
Input
每組數據首先是一個整數C(C <= 100),代表小島的個數,接下來是C組座標,代表每個小島的座標,這些座標都是 0 <= x, y <= 1000的整數。
Output
Sample Input
2 2 10 10 20 20 3 1 1 2 2 1000 1000
Sample Output
1414.2 oh!
注:是在符合條件的小島上建橋,如果沒有小島符合條件才輸出oh
1.普里姆算法:
#include <iostream> // 普里姆算法
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std;
#define sc(a) scanf("%d",&a)
#define nsc(a,b) scanf("%d %d",&a,&b)
#define pr(a) printf("%d\n",a)
#define mem(a,x) memset(a,x,sizeof(a))
#define lf(i,l,r) for(int i=l;i<r;i++)
#define inf 0x3f3f3f3f
#define N 105
int t,c,tol,vis[N],x[N],y[N];
double spot[N][N],dis[N],sum,maxn;
void solve()
{
lf(i,1,c+1)
dis[i]=spot[1][i];
vis[1]=1;
sum=0;
lf(i,1,c)
{
maxn=inf;
tol=-1;
lf(j,1,c+1)
{
if(!vis[j]&&maxn>dis[j])
{
tol=j;
maxn=dis[j];
}
}
if(tol==-1)
return ;
vis[tol]=1;
sum+=dis[tol];
lf(j,1,c+1)
{
if(!vis[j])
dis[j]=min(dis[j],spot[tol][j]);
}
}
return ;
}
int main()
{
int cnt;
sc(t);
while(t--)
{
sc(c);
cnt=0;
lf(i,1,c+1)
nsc(x[i],y[i]);
lf(i,1,c+1)
{
vis[i]=0;
lf(j,1,c+1)
{
if(i!=j)
{
spot[i][j]=sqrt((double)(x[i]-x[j])*(x[i]-x[j])+(y[i]-y[j])*(y[i]-y[j]));
if(spot[i][j]<10.0||spot[i][j]>1000.0)
spot[i][j]=inf;
else cnt++;
}
else spot[i][j]=inf;
}
}
if(c*c-cnt-c<2)
{
printf("oh!\n");
continue ;
}
solve();
sum*=100;
printf("%.1lf\n",sum);
}
return 0;
}
2.克魯斯卡爾算法:
#include <iostream> // 克魯斯卡爾算法
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std;
#define sc(a) scanf("%d",&a)
#define nsc(a,b) scanf("%d %d",&a,&b)
#define pr(a) printf("%d\n",a)
#define mem(a,x) memset(a,x,sizeof(a))
#define lf(i,l,r) for(int i=l;i<r;i++)
#define inf 0x3f3f3f3f
#define N 105
int t,n,cnt,x[N],y[N],p[N];
double sum;
struct node
{
int s;
int e;
double v;
} spot[N*N];
int cmp(node x,node y)
{
return x.v<y.v;
}
int Find(int x)
{
if(x!=p[x])
{
p[x]=Find(p[x]);
}
return p[x];
}
void solve()
{
sum=0;
lf(i,1,cnt)
{
int xx=Find(spot[i].s);
int yy=Find(spot[i].e);
if(xx!=yy)
{
p[xx]=yy;
sum+=spot[i].v;
}
}
}
int main()
{
sc(t);
while(t--)
{
cnt=1;
sc(n);
lf(i,1,n+1)
nsc(x[i],y[i]);
lf(i,1,n+1)
{
p[i]=i;
lf(j,i+1,n+1)
{
sum=sqrt((double)(x[i]-x[j])*(x[i]-x[j])+(y[i]-y[j])*(y[i]-y[j]));
if(sum>=10&&sum<=1000)
{
spot[cnt].s=i;
spot[cnt].e=j;
spot[cnt++].v=sum;
}
}
}
if(cnt==1)
{
printf("oh!\n");
continue;
}
sort(spot+1,spot+cnt,cmp);
solve();
sum*=100;
printf("%.1lf\n",sum);
}
return 0;
}