生成最小树-prim,Kruskal算法

prim算法:一个辅助数组,用来记录当前到达其他点的最短路程,它是更新点,从第一个点出发,把数组w[]初始化,即第一个点到达其他点的路程,每次选取一个最小的点,在把我

w[k]=0;然后再在改点选取比第一个到达其他点的最小值。即更新。

Kruskal算法:用一个结构体来记录边的性质,边的两端和长度,先把边的长度排序,然后依次选取,在选取时,把边的两端赋值为相等,即代表了同一个分量,所以每次选取都要判断

边的两端值是否相等。所以要用一个辅助数组来标记分量,根据MST性质,最短路程连接的点等于总共的点n-1个,如果用Kruskal算法,它的辅助数组的值将全部相等,这是Kruskal算法的技巧。而且更新恰好为n-1个。

下面以poj1287Networking为列。

用两种方法实现:

prim算法

View Code
 1 #include<stdio.h>
 2 #include<string.h>
 3 int min(int x, int y) 
 4 {
 5   return x < y ? x : y;    
 6 }
 7 const int INF = 0x3f3f3f3f;
 8 int main()
 9 {  
10     int i,j,n,r,p,t,k,sum=0; 
11     int a[51][51],w[3000];
12     while(scanf("%d",&p),p)
13     {  
14       scanf("%d",&n);
15       memset(a,0x3f,sizeof(a));
16       memset(w,0x3f,sizeof(w));
17       for(i=1;i<=n;i++)
18        {
19          scanf("%d%d",&r,&t);
20          scanf("%d",&a[r][t]); 
21          a[t][r]=a[r][t]=min(a[t][r], a[r][t]);
22        }
23        for(i=1;i<=p;i++)
24         w[i]=a[1][i];
25         w[1]=0;
26        for(i=1;i<p;i++)
27           {
28            int min=INF;
29            for(j=1;j<=p;j++) 
30                if(w[j]<min && w[j])
31             {k=j;min=w[j];}             
32            w[k]=0,sum+=min;
33            for(j=1;j<=p;j++)
34             if(w[j]>a[k][j])
35              w[j]=a[k][j];     
36           }
37        printf("%d\n",sum);
38       sum=0;
39       }
40    return 0;
41 }

Kruskal算法:

View Code
 1 #include<cstdio>  
 2 #include<algorithm>  
 3 using namespace std;  
 4 struct node{  
 5        int x,y,c;  
 6        }edge[3000];  
 7 int f[55],n,p;  
 8 bool cmp(node a,node b)  
 9 {  
10   if(a.c<b.c) return 1;  
11   return 0;  
12 }  
13 int find(int x)  
14  {  
15     return x==f[x]?x:find(f[x]);  
16 }  
17 void krusal()  
18 {  
19      int i,sum=0;  
20      for(i=1;i<=p;i++)  
21         f[i]=i;  
22      for(i=0;i<n;i++)  
23       {  
24         int x=find(edge[i].x);   
25         int y=find(edge[i].y);  
26         if(x!=y)  
27          {  
28            f[x]=y;  
29            sum+=edge[i].c;  
30          }  
31       }  
32      printf("%d\n",sum);  
33 }  
34 int main()  
35 {     
36     while(scanf("%d",&p),p)  
37      {    
38         scanf("%d",&n);  
39         for(int i=0;i<n;i++)  
40          scanf("%d%d%d",&edge[i].x,&edge[i].y,&edge[i].c);  
41         sort(edge,edge+n,cmp);  
42         krusal();  
43      }  
44      return 0;  
45 }  

 

 

  

 

posted on 2013-04-26 15:27  青竹士  阅读(1003)  评论(0编辑  收藏  举报

导航