prim算法精讲
prim算法 是从节点的角度 采用贪心的策略 每次寻找距离 最小生成树最近的节点 并加入到最小生成树中。
minDist数组 用来记录 每一个节点距离最小生成树的最近距离。
53. 寻宝(第七期模拟笔试) (kamacoder.com)
#include <iostream>
#include <vector>
#include <climits>
using namespace std;
int main(){
int v = 0, e = 0, v1 = 0, v2 = 0, val = 0;
cin >> v >> e;
vector<int> minDist(v + 1, 10001);
vector<int> visited(v + 1, 0);
vector<vector<int>> map(v + 1, vector<int>(v + 1, 10001));
for(int i = 1; i <= e; i++){
cin >> v1 >> v2 >> val;
map[v1][v2] = val;
map[v2][v1] = val;
}
for(int i = 1; i < v; i++){
int cur = -1, minVal = INT_MAX;
for(int j = 1; j <= v; j++){
if(!visited[j] && minDist[j] < minVal){ // 找距离树最近的节点,第一次默认取第一个节点
cur = j;
minVal = minDist[j];
}
}
visited[cur] = 1; // 加入最小节点树
for(int j = 1; j <= v; j++){
if(!visited[j] && map[j][cur] < minDist[j]){
minDist[j] = map[j][cur];
}
}
}
int ans = 0;
for(int i = 2; i <= v; i++){ // 第一个节点不计
ans += minDist[i];
}
cout << ans;
return 0;
}
kruskal算法精讲
#include <iostream>
#include <vector>
#include <climits>
#include <algorithm>
using namespace std;
struct edge{
int v1 = 0, v2 = 0, val = 0;
};
vector<int> father = vector<int>(10001, 0);
int v;
void init(){
for(int i = 1; i <= v; i++){
father[i] = i;
}
}
int find(int i){
if(i == father[i]){
return father[i];
}
return father[i] = find(father[i]);
}
void join(int i, int j){
i = find(i);
j = find(j);
if(i == j){
return ;
}
father[i] = j;
}
bool ifSame(int i, int j){
return find(i) == find(j);
}
int main(){
int e;
cin >> v >> e;
vector<edge> edges; // 记录每条边
int v1, v2, val;
while (e-- > 0) {
cin >> v1 >> v2 >> val;
edge es;
es.v1 = v1;
es.v2 = v2;
es.val = val;
edges.push_back(es);
}
sort(edges.begin(), edges.end(), [](const edge &a, const edge &b){
return a.val < b.val; // 按照边的权重从小到大排序
});
init(); // 初始化并查集
int ans = 0;
e = edges.size();
for(int i = 0; i < e; i++){
if(!ifSame(edges[i].v1, edges[i].v2)){// 这条边的两个节点还没完全放入树中
join(edges[i].v1, edges[i].v2);
ans += edges[i].val;
}
}
cout << ans;
return 0;
}