53. 寻宝 prim算法
prim算法
cpp
#include <iostream>
#include <vector>
#include <fstream>
#include <climits>
using namespace std;
int main() {
int v, e;
int v1, v2, val;
ifstream infile("input.txt");
cin >> v >> e;
vector<vector<int>> graph(v + 1, vector<int>(v + 1, INT_MAX));
while (e--) {
cin >> v1 >> v2 >> val;
graph[v1][v2] = val;
graph[v2][v1] = val;
}
/*for (int i = 0; i < v + 1; ++i) {
for (int j = 0; j < v + 1; ++j) {
cout << "v1: " << i << " v2: " << j << " val: " << graph[i][j] << endl;
}
}*/
vector<bool> isInTree(v + 1, false);
vector<int> minDest(v + 1, INT_MAX);
// 找到第一个顶点
// 将它放入树中
// 更新minDest
isInTree[1] = true;
for (int j = 1; j < v + 1; ++j) {
if (!isInTree[j] && graph[1][j] < minDest[j])
minDest[j] = graph[1][j];
}
for (int i = 2; i < v; ++i) { // 只需要循环v-1次
int curMin = 0;
int minVal = INT_MAX;
for (int j = 1; j < v + 1; ++j) {
if (!isInTree[j] && minDest[j] < minVal) {
minVal = minDest[j];
curMin = j;
}
}
isInTree[curMin] = true;
for (int j = 1; j < v + 1; ++j) {
if (!isInTree[j] && graph[curMin][j] < minDest[j])
minDest[j] = graph[curMin][j];
}
}
int result = 0;
for (int i = 2; i <= v; ++i) {
result += minDest[i];
}
cout << result << endl;
return 0;
}
kruskal算法
算法思路是按边的val进行从小到大的排序,在不出现环的情况下,将这个边作为最小完全树的一部分。
cpp
#include <iostream>
#include <vector>
#include <fstream>
#include <algorithm>
using namespace std;
struct Edge {
int v1, v2, val;
};
void init(vector<int>& father) {
for (int i = 0; i < father.size(); ++i) {
father[i] = i;
}
}
int find(vector<int>& father, int u) {
if (father[u] == u) return u;
return father[u] = find(father, father[u]);
}
bool same(vector<int>& father, int u, int v) {
u = find(father, u);
v = find(father, v);
if (u == v) return true;
else return false;
}
void join(vector<int>& father, int u, int v) {
u = find(father, u);
v = find(father, v);
if (u == v) return;
else father[v] = u;
}
int main() {
int v, e;
int v1, v2, val;
ifstream infile("input.txt");
cin >> v >> e;
vector<Edge> edges;
while (e--) {
cin >> v1 >> v2 >> val;
edges.emplace_back(Edge{v1, v2, val});
}
/*for (int i = 0; i < v + 1; ++i) {
for (int j = 0; j < v + 1; ++j) {
cout << "v1: " << i << " v2: " << j << " val: " << graph[i][j] << endl;
}
}*/
vector<int> father(v + 1, 0);
sort(edges.begin(), edges.end(), [](const Edge &a, const Edge &b) {
return a.val < b.val;
});
init(father);
int result = 0;
for (Edge edge : edges) {
if (!same(father, edge.v1, edge.v2)) {
join(father, edge.v1, edge.v2);
result += edge.val;
}
}
cout << result << endl;
return 0;
}