最小生成树专题1 最小生成树-Prim算法
原创 已于 2023-10-26 14:46:53 修改 · 粉丝可见 · 123 阅读 · 0 · 0 · 本内容遵循CC 4.0 BY-SA版权协议 版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。 GEO检测 · 编辑
文章链接:https://blog.csdn.net/hacker_51/article/details/134054687
题目:

样例1:
cobol<br/>4 5<br/>0 1 3<br/>0 2 2<br/>0 3 3<br/>2 3 1<br/>1 2 1<br/> |

样例2:
cobol<br/>3 1<br/>0 1 1<br/> |

思路:
Prim算法和 朴素版的 Dijkstra 有点类似,也叫做 朴素版Prim算法,但也还是有点区别。
Dijkstra 中,只要起点到目的点的最短距离。
最小生成树,表示 不定某个起点和终点,要求遍历完所有点的 最短距离。
所以,朴素版的 Prim 和 朴素版的 Dijkstra 很相似。
区别在于更新 dist 的时候,Dijkstra 更新的是距离,Prim 更新的是集合之间的最短边。
即
1 2 3 4
| for(int j = 0;j < n;++j) { dist[j] = min(dist[j],g[t][j]); }
|
最小生成树中,是 找 集合到集合之间的 最小边, Dijkstra最短距离是 节点之间的最小距离。
代码详解如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82
| #include <iostream> #include <vector> #include <queue> #include <cstring> #include <algorithm> #include <unordered_map> #define endl '\n' #define YES puts("YES") #define NO puts("NO") #define INF 0x3f3f3f3f #define umap unordered_map #define All(x) x.begin(),x.end() #pragma GCC optimize(3,"Ofast","inline") #define IOS std::ios::sync_with_stdio(false),cin.tie(0), cout.tie(0) using namespace std; const int N = 500 + 10; int n,k; int g[N][N]; bool st[N]; int dist[N]; inline int Prim() { memset(dist,INF,sizeof dist); dist[0] = 0; int ans = 0; for(int i = 0;i < n;++i) { int t = -1; for(int j = 0;j < n;++j) { if(!st[j] && (t == -1 || dist[j] < dist[t]))t = j; } if(i && dist[t] >= INF) return -1; st[t] = true; if(i) ans += dist[t]; for(int j = 0;j < n;++j) dist[j] = min(dist[j],g[t][j]); } if(ans >= INF) return -1; return ans; } inline void solve() { memset(g,INF,sizeof g); cin >> n >> k; while(k--) { int a,b,c; cin >> a >> b >> c; g[a][b] = g[b][a] = min(g[a][b],c); } cout << Prim() << endl; } int main() {
IOS; int _t = 1;
while (_t--) { solve(); } return 0; }
|
最后提交:
