最小生成树 kruskal 和 pime 模版

kruskal:

View Code
  1 #include <iostream>
  2 #define INF 0x3fff
  3 #define MAXN 100
  4 using namespace std;
  5 typedef struct
  6 {
  7     int s;//start结点 
  8     int e;//end结点 
  9     int w;//weight权值 
 10 }edge;
 11 edge e[MAXN*MAXN/2];//存储每一条边的数组 
 12 void insertsort(edge e[],int n)//直接插入排序 
 13 {
 14     int i,j;
 15     edge temp;
 16     for(i = 0 ; i < n ;i++)
 17     {
 18         temp = e[i];
 19         j = i - 1;
 20         while(j >= 0 && temp.w < e[j].w)
 21         {
 22             e[j+1]= e[j];
 23             j--;
 24         }
 25         e[j+1] = temp;
 26     }
 27 }
 28 void kruskal(int n,int mat[][MAXN])//Kruskal实现 
 29 {
 30     int i,j,k,m1,m2,sn1,sn2;
 31     edge e[MAXN*MAXN/2];
 32     int vset[MAXN];
 33     for(i = 0 ; i < n ; i++)//每个节点都初始化 
 34         vset[i] = i;
 35     k = 0;
 36  
 37     for(i = 0 ; i < n;i++)
 38     {
 39         for(j = 0 ; j < n;j++)
 40         {
 41             if(mat[i][j] != 0 && mat[i][j] != INF)//将邻接矩阵中的每一条边都加入到边权值的数组中 
 42             {
 43                 e[k].s = i;e[k].e = j;
 44                 e[k].w = mat[i][j];
 45                 k++;
 46             }
 47         }
 48     }
 49     insertsort(e,k);//对边的权值从大到小排序,这里采用直接插入排序,如果采用堆排序时间复杂度会减少 
 50     int cnt = 1 ;//记录加入到最小生成树的边的数量 
 51     k = 0;
 52     while(cnt < n)
 53     {
 54         m1 = e[k].s; m2 = e[k].e;//记录这条边的start , end 结点 
 55         sn1 = vset[m1]; sn2 = vset[m2];//看这两个结点属于哪一个set 
 56         if(sn1 != sn2)//如果不等,说明这两个结点不在一个生成树中,合并 
 57         {
 58             printf("edge (%d,%d):%d is added!\n", e[k].s,e[k].e,e[k].w);
 59             cnt++;
 60             for(i = 0 ; i < n ; i++)
 61             {
 62                 if(vset[i] == sn2)//把所有的原有的生成树的结点重新加入到新的生成树中 
 63                     vset[i] = sn1;
 64             }
 65         }
 66         k++;//k为边的权值数组的Index 
 67     }   
 68  
 69 }
 70 int mat[MAXN][MAXN];
 71 int main()
 72 {
 73     memset(mat,0,sizeof(mat));
 74     int num;
 75     printf("please input vertex:");
 76     scanf("%d",&num);
 77     int n;
 78     printf("input the number of edge:");
 79     scanf("%d",&n);
 80     int t = n;
 81     while(t--)
 82     {
 83         int a,b,cost;
 84         scanf("%d %d %d",&a,&b,&cost);
 85         --a,--b;
 86         if(mat[a][b] == 0 && mat[b][a] == 0 || cost < mat[a][b] )
 87             mat[a][b] = mat[b][a] = cost;
 88     }
 89     int i,j;
 90     for(i = 0 ; i < num;i++){
 91         for(j = 0 ; j < num; j++)
 92             printf("%4d",mat[i][j]);printf("\n");}
 93     kruskal(num,mat);
 94 /*
 95 test data:
 96 6
 97 10
 98 1 2 6
 99 1 3 1
100 1 4 5
101 2 3 5
102 3 4 5
103 2 5 3
104 3 5 6
105 3 6 4
106 4 6 2
107 5 6 6
108 */ 
109     return 0;
110 }

更简洁的Kruskal模板:

View Code
 1 #include"iostream"
 2 #include"cstdio"
 3 #include"cstdlib"
 4 #include"algorithm"
 5 using namespace std;
 6 struct node
 7 {
 8     int x,y,l;//分别表示两条边的顶点,及距离
 9 }road[1200];
10 int pre[20];
11 int find( int x )
12 {
13     int r=x;
14     while( pre[r]!=r )
15         r=pre[r];
16     int i=x;
17     int j;
18     while( i!=r )
19     {
20         j=pre[i];
21         pre[i]=r;
22         i=j;
23     }
24     return r;
25 }
26 
27 bool cmp( struct node m,struct node n )
28 {
29     return m.l<n.l;
30 }
31 
32 int main()
33 {
34 
35 //    freopen("input.txt","r",stdin);
36 //    freopen("output.txt","w",stdout);
37     int n;
38     while( scanf("%d",&n)!=EOF )
39     {
40         int i;
41         for( i=0;i<=n;i++ )
42             pre[i]=i;//初始化所有点都是孤立的
43         int k;
44         for( i=0;;i++ )
45         {
46             scanf("%d%d%d",&road[i].x, &road[i].y,&road[i].l);
47             k=i;
48             if( !road[i].x && !road[i].y && !road[i].l )
49                 break;
50         }
51         sort( &road[0],&road[k+1],cmp );
52         int ans=road[0].l;
53         pre[road[0].x]=road[0].y;
54         for( i=1;i<=k;i++ )
55         {
56             if( find( road[i].x)!=find(road[i-1].x) || find( road[i].y )!=find( road[i-1].x ) )
57             {
58                 ans+=road[i].l;
59                 pre[road[i].x]=find( road[i-1].x );
60                 pre[road[i].y]=find( road[i-1].x );
61             }
62         }
63         printf("%d\n",ans);
64 
65     }
66     return 0;
67 }

 

prime 模板:

View Code
 1 #define MAXN
 2 bool flag[MAXN];
 3 double graph[MAXN][MAXN];   // graph[i][j] 表示节点i到j的距离
 4  
 5 double Prim(int n)  // 一共n个节点
 6 {
 7     int i, j, k;
 8     double t, lowcase[105], ans = 0;
 9     for (i = 2; i <= n; i++)
10         lowcase[i] = graph[1][i], flag[i] = false;
11     flag[1] = true;
12  
13     for (i = 1; i < n; i++)
14     {
15         k = 1;
16         t = INF;
17         for (j = 2; j <= n; j++)
18             if (!flag[j] && lowcase[j] < t)
19                 k = j, t = lowcase[j];
20          
21         ans += t;
22         flag[k] = true;
23  
24         for (j = 1; j <= n; j++)
25             if (!flag[j] && graph[k][j] < lowcase[j])
26                 lowcase[j] = graph[k][j];
27     }
28  
29     return ans;
30 }
posted on 2012-08-05 09:23  Zee、  阅读(318)  评论(0编辑  收藏  举报