介绍:
基本图形:
下面对它的长度进行一个排序:
然后将点单拉出来:
把边长从小到大依次加到顶点处,会连成环的顶点就舍弃,直到把所有的点都穿起来。
下面根据要求给出大概的实现代码:(要注意的是判断两个顶点是否在一个集合中,这里用了并查集的方法–一个集合中的顶点连成一棵树)
#include<iostream>
#include<string>
#include<algorithm>
using namespace std;
typedef struct
{
int row,col,val;
}triple;
typedef struct //邻接矩阵
{
string *vertexs; //一维数组存储顶点
triple *adj; //三元元组顺序表存储边(矩阵压缩存储)
int n,e; //顶点个数和边的个数
}MatGraph;
void initGraph(MatGraph &g,int vexN,int edgeN)
{
g.n = vexN;
g.e = edgeN;
g.vertexs = new string[g.n];
g.adj = new triple[g.e];
}
void destroyGraph(MatGraph &g)
{
delete[] g.vertexs;
delete[] g.adj;
}
bool cmp(const triple &a,const triple &b)
{
return a.val < b.val;
}
void createGraph(MatGraph &g)
{
for(int i = 0; i < g.n; i++)
cin>>g.vertexs[i];
int u, v, w;
for(int i = 0; i < g.e; i++)
{
cin>> u >> v >> w;
g.adj[i].row = u;
g.adj[i].col = v;
g.adj[i].val = w;
}
}
int FIND_SET(int *S,int x)
{
while(S[x] >= 0)
x = S[x];
return x;
}
void UNION(int *S,int x,int y)
{
S[x] = y;
}
void minSpanTree_kruskal(MatGraph &g)
{
sort(g.adj , g.adj + g.e, cmp);
for(int i = 0; i < g.e; i++)
{
cout<<"("<<g.adj[i].row<<","<<g.adj[i].col<<")"<<g.adj[i].val<<endl;
}
int *S = new int[g.n];
for(int i = 0; i < g.n; i++)
S[i] = -1;
int i = 0;
int count = 0;
int u, v;
int p1, p2;
while(1 )
{
u = g.adj[i].row;
v = g.adj[i].col;
p1 = FIND_SET(S, u);
p2 = FIND_SET(S, v);
if(p1 != p2)
{
count ++;
cout<<"("<<g.vertexs[u]<<","<<g.vertexs[v]<<")"<<g.adj[i].val<<endl;
UNION(S, p1, p2);
if(count == g.n - 1)break;
}
i++;
}
}
int main()
{
int n, e;
cin >> n >> e;
MatGraph g;
initGraph(g, n, e);
createGraph(g);
minSpanTree_kruskal(g);
destroyGraph(g);
return 0;
}
给出数据:
6 10
v0 v1 v2 v3 v4 v5
0 1 6
0 2 1
0 3 5
1 2 5
1 4 3
2 3 5
2 4 6
2 5 4
3 5 2
4 5 6
在程序中运行后的结果如下:
满足条件。
这里用了并查集查找函数还有并查集合并函数,如果顶点很多的话,可以通过压缩树的高度的方法等提高查找速度。