【问题描述】
已知含有n个顶点的带权连通无向图,采用邻接矩阵存储,邻接矩阵以三元组的形式给出,只给出不包括主对角线元素在内的下三角形部分的元素,且不包括不相邻的顶点对。求该连通图的最小生成树的权值
【输入形式】
第一行给出结点个数n和三元组的个数count,以下每行给出一个三元组,数之间用空格隔开。(注意这里顶点的序号是从1到n,而不是0到n-1,程序里要小心!)
【输出形式】
最小生成树的权值
思路代码:
#include<iostream>
#include<fstream>
#include<string>
#include<vector>
#include<sstream>
#include<map>
#include<stack>
#include<queue>
#include<functional>
#include<unordered_set>
#include<algorithm>
#include<utility>
#include <limits.h>
#include<unordered_map>
using namespace std;
void findnext(unordered_set<int>& mask, map<pair<int,int>, int>& wegt,int &ans) {
int minw = INT_MAX;
int v;
//遍历边集,找到权重最小且一个点属于mask一个点不属于mask的边,再把不属于mask的边加入到mask中
for (auto &x : wegt) {
int m = x.first.first;
int n = x.first.second;
if ((mask.count(m) && !mask.count(n) || mask.count(n) && !mask.count(m)) && x.second <= minw) {
minw = x.second;
if (mask.count(m)) v = n;
else v = m;
}
}
ans += minw;
mask.insert(v);
}
int main() {
int n, count;
while (cin >> n) {
cin >> count;
unordered_set<int>mask{ 1 };
map<pair<int,int>, int>wegt = {};
for (int i = 0; i < count; ++i) {
int v1, v2, w;
cin >> v1 >> v2 >> w;
//在存储边的过程中,两个点之间只留一条权重最小边
pair<int,int> pr1 = make_pair(v1, v2),pr2 = make_pair(v2,v1);
if (wegt.count(pr1) != 0 || wegt.count(pr2) != 0) {
if (wegt.count(pr1) != 0 && wegt[pr1] > w) wegt[pr1] = w;
else if (wegt.count(pr2) != 0 && wegt[pr2] > w) wegt[pr2] = w;
}
else wegt[pr1] = w;
}
int ans = 0;
while (mask.size() != n) {
findnext(mask, wegt, ans);
}
cout << ans << endl;
}
}
//运用prim算法