最小生成树 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 }