最小生成树 普里姆(prim)算法
prim的基本思想是对图G(V,E)设置集合S来存放已经被访问的顶点
- 每次从集合V-S(未加入最小生成树的节点)中选择与集合S最近点顶点u(用d[u]记录u与S的最短距离),将u加入集合S,同时将这个节点与集合S最近的边加入最小生成树
- 以顶点u作为集合S与V-S的接口,优化从u出发能达到的且还未访问的顶点v与集合S的最短距离即max(d[v],G[u][v]);
具体实现
int prim() { fill(d, d + maxn, INF); //最开始所有点离集合S的距离为INF d[0] = 0; //起点可以任意选择,这里以0为起点 int ans = 0; //记录最小生成树的总权重 for (int i = 0; i < n; ++i) { int u = -1, MIN = INF; for (int j = 0; j < n; ++j) { if (vis[j] == false && d[j] < MIN) { u = j; MIN = d[j]; } } if (u == -1) return; vis[u] = true; //将u并入集合S ans += d[u]; //增加权重 for (int v = 0; v < n; ++v) { //从u出发能到达的且未访问的节点v的距离G[u][v]比当前的d[v]短 if (vis[v] == false && G[u][v] != INF && G[u][v] < d[v]) { d[v] = G[u][v]; //优化距离 } } } return ans;//返回最小生成树的总权重 }