对于图 (V, E),有N个节点,求解最小生成树 TE
#include <iostream>
#include <string.h>
#include <vector>
#include <algorithm>
using namespace std;
const int MAX_NUM = 100;
typedef struct Edge{
int point1; /* 边的端点1 */
int point2; /* 边的端点2 */
int weight; /*边的权值*/
} Edge;
Edge edge[MAX_NUM]; /* 存储边*/
int node[MAX_NUM]; /*存储对应顶点的祖先*/
bool cmp(const Edge &e1, const Edge &e2)
{
return e1.weight < e2.weight;
}
/* 寻找节点x的祖先
例如node[2]=1 node[8]=1 ,node[3]=1,
共同的祖先是1, 如果此时加入边(3,8)加进去,则构成回路,
不能加入到最小生成树中*/
int find(int x)
{
return node[x] == x ? x : node[x] = find(node[x]);
}
int kruskal(int N, int E) /*N: 顶点数E:边数*/
{
int ret = 0;
int count = 0;
/*初始化node值为序号*/
for(int i = 0; i < E; i++)
node[i] = i;
/*按照weight值从小到大排序*/
sort(edge, edge+E, cmp);
for(int i = 0; i < E; i++) {
int x = find(edge[i].point1);
int y = find(edge[i].point2);
/*如果x==y,则表明他们有共同的祖先,会构成回路,进行下一次迭代*/
if(x != y) {
/* 叠加weight到结果值ret中,并更新node值
此处即为TE的生成过程,如果想要知道详细路径可以在此记录 */
ret += edge[i].weight;
if (x < y) {
node[x] = y;
} else {
node[y] = x;
}
}
/*迭代次数达标,已经产生了N-1条边,构成了最小生成树*/
if (count == N-1)
break;
}
return ret;
}
int main()
{
memset(node, 0, sizeof(node));
memset(edge, 0, sizeof(edge));
int N; /*顶点数*/
int E; /*边数*/
cin >> N;
cin >> E;
for (int i = 0; i < E; ++i) {
cin >> edge[i].point1;
cin >> edge[i].point2;
cin >> edge[i].weight;
}
cout << kruskal(E) << endl;
return 0;
}