prim算法适合稠密图,其时间复杂度为O(n^2),其时间复杂度与边得数目无关,而kruskal算法的时间复杂度为O(eloge)跟边的数目有关,适合稀疏图。
一、 普利姆算法(prim)
1 // 可以输出最短路中的边 2 #define inf 0x3f3f3f3f 3 int n,mindis; //n个顶点 4 int map[1000][1000]; // 边的权值 5 int vis[1000]; // 标记变量 1表示此下标的顶点已经加入生成树 6 int dis[1000]; // 出发点到该下标的权值 7 void prim() 8 { 9 int i,j,mindis = 0,min,pos; 10 for(i = 1; i <= n; i ++) 11 { 12 dis[i] = map[1][i]; 13 vis[i] = 1; 14 } 15 vis[1] = -1; // 起点已经加入生成树 16 for (i = 1; i < n; i ++) // 循环除起点外的其他顶点 17 { 18 min = inf; pos = -1; 19 for (j = 1; j <= n; j ++) // 寻找最小权值 20 { 21 if (vis[j] != -1 && dis[j] < min) 22 { 23 min = dis[j]; 24 pos = j; 25 } 26 } 27 if (pos != -1) 28 { 29 // printf("%d %d ",vis[pos],pos); // 输出加入最短路的边 30 mindis += min; 31 vis[pos] = -1; // 标记 32 for (j = 1; j <= n; j ++) // 更新权值 33 if (vis[j]!=-1 && dis[j] > map[pos][j]) 34 { 35 dis[j] = map[pos][j]; 36 vis[j] = pos; 37 } 38 } 39 40 } 41 printf("%d ",mindis); 42 }
1 // 只计算最小生成树的权值,不输出构成最小生成树的边,可以将dis数组和vis数组合并 2 #define inf 0x3f3f3f3f 3 int map[100][100]; 4 int dis[100]; 5 int n; 6 void prim() // 起始点为 1 7 { 8 int i,j,pos,min,sum = 0; 9 for (i = 1; i <= n; i ++) 10 dis[i] = map[1][i]; 11 dis[1] = -1; 12 for (i = 1; i < n; i ++) 13 { 14 min = inf; pos = -1; 15 for (j = 1; j <= n; j ++) 16 { 17 if (dis[j] != -1 && dis[j] < min) 18 { 19 pos = j; 20 min = dis[j]; 21 } 22 } 23 sum += min; 24 dis[pos] = -1; 25 for (j = 1; j <= n; j ++) 26 { 27 if (map[pos][j] < dis[j]) 28 dis[j] = map[pos][j]; 29 } 30 } 31 printf("%d ",sum); 32 }
一、 克鲁斯卡尔算法(kruskal)
1 struct point 2 { 3 int x,y,l; 4 }p[11000]; 5 int parent[110],n; 6 int x[110],y[110]; // 存放边的顶点 7 bool cmp(point a, point b) 8 { 9 return a.l < b.l; 10 } 11 int find(int x) // 寻找根节点 12 { 13 int s,tmp; 14 for (s = x; parent[s] >= 0; s = parent[s]); 15 while (s != x) // 路径压缩 使后面的查找更快速 16 { 17 tmp = parent[x]; 18 parent[x] = s; 19 x = tmp; 20 } 21 return s; 22 } 23 void Union(int A, int B) // 将两个不同集合的元素合并,使两个集合中任意两个元素都连通 24 { 25 int a = find(A), b = find(B); 26 int tmp = parent[a]+parent[b]; // 和为负数 27 if (parent[a] < parent[b]) 28 { 29 parent[b] = a; 30 parent[a] = tmp; 31 } 32 else 33 { 34 parent[a] = b; 35 parent[b] = tmp; 36 } 37 } 38 void kruskal(int 边数) 39 { 40 int sum = 0; 41 int u,v,i,j = 0; 42 sort(p,p+边数,cmp); 43 memset(parent,-1,sizeof(parent)); 44 for (i = 0; i <= k; i ++) 45 { 46 u = p[i].x; v = p[i].y; 47 if (find(u) != find(v)) 48 { 49 sum += p[i].l; 50 Union(u,v); 51 j ++; 52 } 53 if (j == n-1) break; 54 } 55 printf("%d ",sum); 56 }