1. 问题
在一个无向图G=(V,E)中,(u,v)代表连接顶点u与顶点v的边,而w(u,v)代表此边的权重,若存在T为E的子集且无循环图,使得w(T)最小,则此T为G的最小生成树。
2. 解析
Prim算法:
Kruskal算法:
3. 设计
Prim算法:
void prim(int x) {//参数为默认的初始访问点
visit[x] = 1;//visit数组判断是否被访问,1为被访问过,0为未被访问过
for (多次循环) {
min = 1000;//每次初始化min
for (遍历所有点)
{
if (如果该点被访问过) {
for (temp = first[i]; temp; temp = temp->link) //搜索与该点相关的边
{
if (该边已经取到了)
{
continue;
}
else if (该边的权重比min小)
{
min = temp->quan;
minbiao = temp->nextbiao;//更新min和下标
}
}
}
}
visit[minbiao] = 1;
sumweight = sumweight + min;
}
printf_s("the minmum weight is %d.", sumweight);
}
Kruskal算法:
void Kruskal() {
scanf_s("%d", &v);//输出边的数量
for (int i = 0; i < MAXG; i++)//初始化parent数组
{
parent[i] = -1;
}
for (int i = 0; i < v; i++)//输入图
{
scanf_s("%d %d %d", &edge[i].a, &edge[i].b, &edge[i].weight);
//a,b为边的两个顶点,weight为权重
}
for (int i = 0; i < v; i++)//对权重进行排序
{
for (int j = 1; j < v - i; j++)
{
if (edge[j].weight < edge[j - 1].weight)
{
//交换edge[j]和edge[j-1]的a,b,weight
}
}
}
int sumweight = 0;
for (遍历所有边)
{
if (edge[i].a和edge[i].b可以合并) {
sumweight = sumweight + edge[i].weight;
}
else
{
continue;
}
}
printf_s("the minmum weight is %d.", sumweight);
}
4. 源码
https://github.com/LonelyTaker/Algorithm-analysis