您的位置:首页 > 其它

UVA 10034 Freckles 最小生成树

2013-08-03 10:59 501 查看
虽然是道普通的最小生成树题目,可还是中间出了不少问题,暴露的一个问题是不够细心,不够熟练。所以这篇博客就当记录一下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
;

typedef struct
{
int u,v;
double c;
} EDGE;
EDGE edge[N*N/2+10];
int m,tc,n,pre
;

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-9)
return 0;
return x>0?1:-1;

}
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]>=0; 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=0;
memset(pre,-1,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=0; 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-1)
break;
}
return ans;
}

void input(void)
{
m=0;
scanf("%d",&n);
int i,j;
for(i=0; i<n; i++)
scanf("%lf%lf",&point[i].x,&point[i].y);

for(i=0; i<n-1; i++)
for(j=i+1; 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 0;
}


代码二:prim

#include<cstdio>
#include<iostream>
#include<cmath>
#include<cstring>
#define N 110
#define INF 1000000000000000/*这里要开大于点,不然WA*/

using namespace std;
int n,tc;
double dis

;
double x
,y
;

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=0; i<n; i++)
scanf("%lf%lf",x+i,y+i);
for(i=0; i<n-1; i++)
for(j=i+1; j<n; j++)
dis[i][j]=dis[j][i]=cal(x[i],y[i],x[j],y[j]);
}

double Prim(void)
{
double lowcost
;
int vis
;
memset(vis,0,sizeof(vis));
for(int i=0; i<N; i++)
lowcost[i]=INF;
vis[0]=-1;
int e=0,i;
double ans=0;
for(int k=0; k<n-1; k++)
{
double micost=INF;
int miedge=-1;
for( i=0; i<n; i++)
if(vis[i]!=-1)
{
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]=-1;/*用来记录下次加入的点*/
}
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 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: