#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
class Subset
{//并查集类
public:
int* parent; //每个子集的根
int* rank; //每个子集的秩
Subset(int n)
{//构造函数初始化
parent = new int[n];
rank = new int[n];
for (int i = 0; i < n; i++)
{
parent[i] = i;
rank[i] = 0;
}
}
int find(int x) //找x的root
{
if (parent[x] != x)
{
parent[x] = find(parent[x]); //压缩路径
}
return parent[x];
}
void unionSet(int x, int y)
{//合并x合y所在的子集
int xroot = find(x);
int yroot = find(y);
if(xroot == yroot)
{
return ;
}
if (rank[xroot] < rank[yroot])
{
parent[xroot] = yroot;
}
else if (rank[xroot] > rank[yroot])
{
parent[yroot] = xroot;
}
else
{
parent[yroot] = xroot;
rank[xroot]++;
}
}
};
class Edge
{
public:
int src; //起始顶点
int dest; //目标顶点
int weight;
Edge(int _src, int _dest, int _weight)
{
src = _src;
dest = _dest;
weight = _weight;
}
Edge():src(0),dest(0),weight(0){}
bool operator < (const Edge &b) const
{//运算符重载
return weight < b.weight;
}
};
/*
class cmp
{
public:
bool operator () (Edge a, Edge b) //从小到大排
{
return a.weight < b.weight;
}
};
*/
class Graph
{
public:
int V; //顶点数
vector<Edge> edge;
Graph(int v):V(v),edge(0){}
void kruskal()
{
vector<Edge> result; //存放最小生成树的路径
//cmp cmp1;
//sort(edge.begin(), edge.end(),cmp1);
sort(edge.begin(), edge.end()); //对所有边按权重从小到大排序
Subset subsets(V); //创键并查集对象,V为顶点数
int i = 0;
while (i < edge.size()) //处理所有的边
{
int x = subsets.find(edge[i].src);
int y = subsets.find(edge[i].dest);
if (x != y) //在不在同一个集合(连同分量)
{
subsets.unionSet(x, y);
result.push_back(edge[i]);
}
i++;
}
//输出最小生成树的边
vector<Edge>::iterator it;
for (it = result.begin(); it != result.end(); it++)
{
cout << it->src << "-->" << it->dest <<" == "<<it->weight << endl;
}
}
};
int main()
{
Graph g1(4);
g1.edge.push_back(Edge(0, 1, 10));
g1.edge.push_back(Edge(0, 2, 6));
g1.edge.push_back(Edge(0, 3, 5));
g1.edge.push_back(Edge(1, 3, 15));
g1.edge.push_back(Edge(2, 3, 4));
g1.kruskal();
return 0;
}
输出:
输入的图:
输出的图: