题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1875
一直超时了,找了好久才发现我把快排比较中的>写成了-。郁闷。
Kruskal算法(基于并查集)
#include<stdio.h>
#include<string.h>
#include<math.h>
#include<stdlib.h>
int v[105];
struct node
{
int x;
int y;
double dis;
}p[10005];
int cmp(const void *a,const void *b)
{
return (*(struct node*)a).dis>(*(struct node*)b).dis?1:-1;
}
int find(int x)
{
if(x!=v[x])
v[x]=find(v[x]);
return v[x];
}
int make(int a,int b)
{
int x,y;
x=find(a);
y=find(b);
if(x==y)
return 0;
v[x]=y;
return 1;
}
int main()
{
int t,n,x[105],y[105],count,i,j,d,k;
double sum;
scanf("%d",&t);
while(t--)
{
scanf("%d",&n);
for(i=1;i<=n;i++)
v[i]=i;
for(i=1;i<=n;i++)
scanf("%d%d",&x[i],&y[i]);
k=0;
for(i=1;i<n;i++)
for(j=i+1;j<=n;j++)
{
d=(x[i]-x[j])*(x[i]-x[j])+(y[i]-y[j])*(y[i]-y[j]);
if(d>=100&&d<=1000000)//判断合适的边,用结构体存城市和边权
{
p[k].x=i;
p[k].y=j;
p[k].dis=sqrt(d);
k++;
}
}
qsort(p,k,sizeof(p[0]),cmp);
sum=count=0;
for(i=0;i<k;i++)
{
if(make(p[i].x,p[i].y)==1)
{
sum+=p[i].dis*100;
count++;
}
}
if(count==n-1)
printf("%.1f\n",sum);
else
printf("oh!\n");
}
return 0;
}
Prime算法(基于最短路)
#include<stdio.h>#include<string.h>
#include<math.h>
#include<stdlib.h>
#define Max 99999999
int flag[105];
double map[105][105];
double dis[105];
double prime(int n)
{
int i,w,tep;
double min,sum=0;
memset(flag,0,sizeof(flag));
for(i=1;i<=n;i++)
dis[i]=map[1][i];//起点到其他个点的最初路径长度
flag[1]=1;//标记已搜过
w=n-1;
while(w--)
{
min=Max;
tep=-1;
for(i=1;i<=n;i++)
{
if(flag[i]==0&&min>dis[i])//遍历搜索到最小的dis值,并记录改点编号
{
min=dis[i];
tep=i;
}
}
if(tep==-1)//若mini为无穷大,则表示改点为孤立点,此图不连通,结束循环
{
return -999;
break;
}
flag[tep]=1;//把搜到的最小的dis值的顶点编号标记
sum+=min;//加上权值
for(i=1;i<=n;i++)
{
if(flag[i]==0&&dis[i]>map[tep][i])//更新每个点的dis值,保证最优
dis[i]=map[tep][i];
}
}
return sum;
}
int main()
{
int t,n,x[105],y[105],i,j,d;
double sum;
scanf("%d",&t);
while(t--)
{
scanf("%d",&n);
for(i=1;i<=n;i++)
scanf("%d%d",&x[i],&y[i]);
for(i=1;i<=n;i++)
for(j=1;j<=n;j++)
map[i][j]=Max;
for(i=1;i<n;i++)
for(j=i+1;j<=n;j++)
{
d=(x[i]-x[j])*(x[i]-x[j])+(y[i]-y[j])*(y[i]-y[j]);
if(d>=100&&d<=1000000)
{
map[i][j]=map[j][i]=sqrt(d);
}
}
sum=prime(n);
if(sum==-999)
printf("oh!\n");
else
printf("%.1f\n",sum*100);
}
return 0;
}