虽然是道普通的最小生成树题目,可还是中间出了不少问题,暴露的一个问题是不够细心,不够熟练。所以这篇博客就当记录一下bug吧。
代码一:kruskal
1 #include<stdio.h> 2 #include<math.h> 3 #include<stdlib.h> 4 #include<string.h> 5 #define N 110 6 7 typedef struct 8 { 9 double x,y; 10 } Point; 11 Point point[N]; 12 13 typedef struct 14 { 15 int u,v; 16 double c; 17 } EDGE; 18 EDGE edge[N*N/2+10]; 19 int m,tc,n,pre[N]; 20 21 double cal(Point a,Point b) 22 { 23 return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y)); 24 } 25 int dblcmp(double x) 26 { 27 if(fabs(x)<1e-9) 28 return 0; 29 return x>0?1:-1; 30 31 } 32 int cmp(const void*i,const void*j) 33 { 34 EDGE *a=(EDGE*)i; 35 EDGE *b=(EDGE*)j; 36 37 return dblcmp(a->c-b->c); 38 39 } 40 void add_edge(int u,int v,double c) 41 { 42 edge[m].u=u; 43 edge[m].v=v; 44 edge[m].c=c; 45 m++;/*记得更新*/ 46 } 47 48 int find(int u) 49 { 50 int x=u; 51 for(; pre[x]>=0; x=pre[x]) ;/*条件判断应该是是pre[x]>=0*/ 52 while(x!=u) 53 { 54 int t=pre[u]; 55 pre[u]=x; 56 u=t; 57 } 58 return x; 59 } 60 61 double kruskal(void) 62 { 63 double ans=0.0; 64 int num=0; 65 memset(pre,-1,sizeof(pre)); 66 int i; 67 qsort(edge,m,sizeof(EDGE),cmp);/*sort before algorithm*/ 68 /*for(i=0;i<m;i++) 69 printf("%f ",edge[i].c); */ 70 for(i=0; i<m; i++) 71 { 72 int u=edge[i].u; 73 int v=edge[i].v; 74 int x,y; 75 if((x=find(u))!=(y=find(v))) 76 { 77 ans=ans+edge[i].c; 78 pre[x]=y; 79 num++; 80 } 81 if(num==n-1) 82 break; 83 } 84 return ans; 85 } 86 87 88 void input(void) 89 { 90 m=0; 91 scanf("%d",&n); 92 int i,j; 93 for(i=0; i<n; i++) 94 scanf("%lf%lf",&point[i].x,&point[i].y); 95 96 for(i=0; i<n-1; i++) 97 for(j=i+1; j<n; j++) 98 { 99 double s=cal(point[i],point[j]); 100 add_edge(i,j,s); 101 } 102 103 } 104 105 void solve() 106 { 107 double mst; 108 mst=kruskal(); 109 printf("%.2f ",mst); 110 if(tc) 111 puts(""); 112 } 113 114 int main(void) 115 { 116 scanf("%d",&tc); 117 while(tc--) 118 { 119 input(); 120 solve(); 121 } 122 return 0; 123 }
代码二:prim
1 #include<cstdio> 2 #include<iostream> 3 #include<cmath> 4 #include<cstring> 5 #define N 110 6 #define INF 1000000000000000/*这里要开大于点,不然WA*/ 7 8 using namespace std; 9 int n,tc; 10 double dis[N][N]; 11 double x[N],y[N]; 12 13 double cal(double x1,double y1,double x2,double y2) 14 { 15 return sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2)); 16 } 17 18 void input(void) 19 { 20 scanf("%d",&n); 21 int i,j; 22 for(i=0; i<n; i++) 23 scanf("%lf%lf",x+i,y+i); 24 for(i=0; i<n-1; i++) 25 for(j=i+1; j<n; j++) 26 dis[i][j]=dis[j][i]=cal(x[i],y[i],x[j],y[j]); 27 } 28 29 double Prim(void) 30 { 31 double lowcost[N]; 32 int vis[N]; 33 memset(vis,0,sizeof(vis)); 34 for(int i=0; i<N; i++) 35 lowcost[i]=INF; 36 vis[0]=-1; 37 int e=0,i; 38 double ans=0; 39 for(int k=0; k<n-1; k++) 40 { 41 double micost=INF; 42 int miedge=-1; 43 for( i=0; i<n; i++) 44 if(vis[i]!=-1) 45 { 46 double temp=dis[e][i]; 47 if(temp<lowcost[i]) 48 { 49 lowcost[i]=temp; 50 vis[i]=e; 51 } 52 if(lowcost[i]<micost) 53 micost=lowcost[miedge=i]; 54 } 55 ans+=micost; 56 e=miedge;/*表示miedge这个顶点作为加入点*/ 57 vis[miedge]=-1;/*用来记录下次加入的点*/ 58 } 59 return ans; 60 } 61 62 void solve(void) 63 { 64 double mst=Prim(); 65 printf("%.2f ",mst); 66 if(tc) 67 puts(""); 68 } 69 70 int main() 71 { 72 scanf("%d",&tc); 73 while(tc--) 74 { 75 input(); 76 solve(); 77 } 78 return 0; 79 }