举一个实例,画出采用Prim算法构造最小生成树的过程
Prim算法的基本思想:
从图中任意取出一个顶点,把它当成一棵树,然后从这棵树相接的边中选择一条最短的边(权值最小)的边,并将这条边及其所连接的顶点也一起并入到这棵树中,此时得到的是一颗有两个顶点的树,然后从这棵树相接的边中选取一条最短的边,并将这条边及其所连接的顶点也一起并入到当前的树中,得到一颗具有三个节点的树,以此类推直到所有的顶点的纳入到树中为止,此时得到的树是最小生成树
#include<iostream>
#include<stdlib.h>
#include<fstream>
using namespace std;
#define MAX 100
#define MAXCOST 0x7fffffff
int graph[MAX][MAX];
int prim(int graph[][MAX], int n)
{
int lowcost[MAX];
int mst[MAX];
int i, j, min, minid, sum = 0;
for (i = 2; i <= n; i++)
{
lowcost[i] = graph[1][i];
mst[i] = 1;
}
mst[1] = 0;
for (i = 2; i <= n; i++)
{
min = MAXCOST;
minid = 0;
for (j = 2; j <= n; j++)
{
if (lowcost[j] < min && lowcost[j] != 0)
{
min = lowcost[j];
minid = j;
}
}
cout << "V" << mst[minid] << "-V" << minid << "=" << min << endl;
sum += min;
lowcost[minid] = 0;
for (j = 2; j <= n; j++)
{
if (graph[minid][j] < lowcost[j])
{
lowcost[j] = graph[minid][j];
mst[j] = minid;
}
}
}
return sum;
}
int main()
{
int i, j, k, m, n;
int x, y, cost;
cin >> m >> n;
for (i = 1; i <= m; i++)
{
for (j = 1; j <= m; j++)
{
graph[i][j] = MAXCOST;
}
}
for (k = 1; k <= n; k++)
{
cin >> i >> j >> cost;
graph[i][j] = cost;
graph[j][i] = cost;
}
cost = prim(graph, m);
cout << "最短距离=" << cost << endl;
system("pause");
return 0;
}
举一个实例,画出采用Kruskal算法构造最小生成树的过程
Kruskal算法是基于贪心的思想得到的。首先我们把所有的边按照权值先从小到大排列,接着按照顺序选取每条边,如果这条边的两个端点不属于同一集合,那么就将它们合并,直到所有的点都属于同一个集合为止。至于怎么合并到一个集合,那么这里我们就可以用到一个工具——-并查集(不知道的同学请移步:Here)。换而言之,Kruskal算法就是基于并查集的贪心算法。
#include<iostream>
#include<fstream>
#include<vector>
#include<algorithm>
using namespace std;
const int Maxvertex = 10;
const int MaxEdge = 100;
struct EdgeType
{
int from, to;
int weight;
};
template<class T>
struct EdgeGraph
{
T vertex[Maxvertex];
vector<EdgeType> edge;
int vertexNum, edgeNum;
};
int FindRoot(int parent[], int v)
{
int t = v;
while(parent[t]> -1)
t = parent[t];
return t;
}
void Kruskal(EdgeGraph<int> G)
{
int parent[Maxvertex];
for (int i = 0; i < G.vertexNum; i++)
parent[i] = -1;
for (int num = 0, i = 0; i < G.edgeNum; i++) {
int vex1 = FindRoot(parent, G.edge[i].from);
int vex2 = FindRoot(parent, G.edge[i].to);
if (vex1 != vex2) {
cout << G.edge[i].from << G.edge[i].to << endl;
parent[vex2] = vex1;
num++;
if (num == G.vertexNum - 1)
return;
}
}
}
bool sort_by_weight(EdgeType&k1, EdgeType&k2)
{
return k1.weight < k2.weight;
}
int main()
{
EdgeGraph<int> Edgraph;
cin >> Edgraph.vertexNum >> Edgraph.edgeNum;
for (int k = 0; k <Edgraph.edgeNum; k++)
{
EdgeType temp;
cin >> temp.from >> temp.to >> temp.weight;
Edgraph.edge.push_back(temp);
}
sort(Edgraph.edge.begin(), Edgraph.edge.end(), sort_by_weight);
Kruskal(Edgraph);
return 0;
}