虽然是道普通的最小生成树题目,可还是中间出了不少问题,暴露的一个问题是不够细心,不够熟练。所以这篇博客就当记录一下bug吧。
代码一:kruskal
#include<stdio.h>
#include<math.h>
#include<stdlib.h>
#include<string.h>
#define N 110 typedef struct
{
double x,y;
} Point;
Point point[N]; typedef struct
{
int u,v;
double c;
} EDGE;
EDGE edge[N*N/+];
int m,tc,n,pre[N]; double cal(Point a,Point b)
{
return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
}
int dblcmp(double x)
{
if(fabs(x)<1e-)
return ;
return x>?:-; }
int cmp(const void*i,const void*j)
{
EDGE *a=(EDGE*)i;
EDGE *b=(EDGE*)j; return dblcmp(a->c-b->c); }
void add_edge(int u,int v,double c)
{
edge[m].u=u;
edge[m].v=v;
edge[m].c=c;
m++;/*记得更新*/
} int find(int u)
{
int x=u;
for(; pre[x]>=; x=pre[x]) ;/*条件判断应该是是pre[x]>=0*/
while(x!=u)
{
int t=pre[u];
pre[u]=x;
u=t;
}
return x;
} double kruskal(void)
{
double ans=0.0;
int num=;
memset(pre,-,sizeof(pre));
int i;
qsort(edge,m,sizeof(EDGE),cmp);/*sort before algorithm*/
/*for(i=0;i<m;i++)
printf("%f\n",edge[i].c); */
for(i=; i<m; i++)
{
int u=edge[i].u;
int v=edge[i].v;
int x,y;
if((x=find(u))!=(y=find(v)))
{
ans=ans+edge[i].c;
pre[x]=y;
num++;
}
if(num==n-)
break;
}
return ans;
} void input(void)
{
m=;
scanf("%d",&n);
int i,j;
for(i=; i<n; i++)
scanf("%lf%lf",&point[i].x,&point[i].y); for(i=; i<n-; i++)
for(j=i+; j<n; j++)
{
double s=cal(point[i],point[j]);
add_edge(i,j,s);
} } void solve()
{
double mst;
mst=kruskal();
printf("%.2f\n",mst);
if(tc)
puts("");
} int main(void)
{
scanf("%d",&tc);
while(tc--)
{
input();
solve();
}
return ;
}
代码二:prim
#include<cstdio>
#include<iostream>
#include<cmath>
#include<cstring>
#define N 110
#define INF 1000000000000000/*这里要开大于点,不然WA*/ using namespace std;
int n,tc;
double dis[N][N];
double x[N],y[N]; double cal(double x1,double y1,double x2,double y2)
{
return sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));
} void input(void)
{
scanf("%d",&n);
int i,j;
for(i=; i<n; i++)
scanf("%lf%lf",x+i,y+i);
for(i=; i<n-; i++)
for(j=i+; j<n; j++)
dis[i][j]=dis[j][i]=cal(x[i],y[i],x[j],y[j]);
} double Prim(void)
{
double lowcost[N];
int vis[N];
memset(vis,,sizeof(vis));
for(int i=; i<N; i++)
lowcost[i]=INF;
vis[]=-;
int e=,i;
double ans=;
for(int k=; k<n-; k++)
{
double micost=INF;
int miedge=-;
for( i=; i<n; i++)
if(vis[i]!=-)
{
double temp=dis[e][i];
if(temp<lowcost[i])
{
lowcost[i]=temp;
vis[i]=e;
}
if(lowcost[i]<micost)
micost=lowcost[miedge=i];
}
ans+=micost;
e=miedge;/*表示miedge这个顶点作为加入点*/
vis[miedge]=-;/*用来记录下次加入的点*/
}
return ans;
} void solve(void)
{
double mst=Prim();
printf("%.2f\n",mst);
if(tc)
puts("");
} int main()
{
scanf("%d",&tc);
while(tc--)
{
input();
solve();
}
return ;
}