最小生成树
kruskal
每次加入最小的 两端点不相连的路径
1 void kruskal(){ 2 int i, j; 3 for(i = 1; i <= m; i++){ 4 if(find(edge[i].u) != find(edge[i].v)){ 5 fa[find(edge[i].u)] = find(edge[i].v ); 6 ans += edge[i].w; 7 } 8 } 9 for(i = 1; i <= n; i++){ 10 if(find(i) != find(1)){ 11 printf("orz"); 12 return ; 13 } 14 } 15 printf("%d", ans); 16 }
prim
每次选择与当前集合距离最近的点 加入集合并松弛
1 void prim(){ 2 int i, j, k; 3 int goal; 4 int mn; 5 6 memset(intree, 0, sizeof(intree)); 7 memset(distt, INF, sizeof(distt)); 8 distt[1] = 0; 9 10 for(i = 1; i <= n; i++){ 11 12 //以下为寻找到集合最近的点 13 mn = INF; 14 goal = -1; 15 for(j = 1; j <= n; j++){ 16 if(intree[j])continue; 17 if(distt[j] < mn){ 18 mn = distt[j]; 19 goal = j; 20 } 21 } 22 intree[goal] = 1; 23 24 //cout << mn << endl; 25 ans += mn; 26 27 if(goal == -1){ 28 printf("orz\n"); 29 return ; 30 } 31 32 //以下循环为点到集合距离的维护 33 k = head[goal]; 34 while(k != -1){ 35 if(w[k] < distt[v[k]]){ 36 distt[v[k]] = w[k]; 37 } 38 k = next[k]; 39 } 40 } 41 printf("%d\n", ans); 42 }
相关题目: