最小生成树

Prim与kruskal算法

输入为(顶点个数、顶点名称)

6
v1 v2 v3 v4 v5 v6 

(邻接矩阵已给出)

#include<iostream>
using namespace std;
int MAX = 0x7FFFFFF;
int MAT[6][6] =
{
	0,6,1,5,0,0,
	6,0,5,0,3,0,
	1,5,0,5,6,4,
	5,0,5,0,0,2,
	0,0,6,0,0,6,
	0,0,4,2,6,0
};
class Graph
{
	int vex;
	int mat[20][20];
	char name[20][20];

public:
	void kruskal()
	{
		//使用root数组记录根相同的节点,初始化时每一个节点的根都为其自身
		//最小生成树的边共有n-1条,于是主循环至少进行n-1次
		//每一次循环从邻接矩阵中找到最短边,并将其改为无限大
		//1.最短边的出点与入点的根若不相同,则将全部与入点根相同的点的根设为出点根,循环次数t--
		//2.最短边的出点与入点的根若相同,则抛弃该最短边,进行下一次循环
		int root[20];
		for (int i = 0;i < vex;i++)
			root[i] = i;

		int t = vex - 1;
		while (t)
		{
			int min = MAX;
			int in, out;
			for (int i = 0;i < vex;i++)
				for (int j = i;j < vex;j++)
					if (mat[i][j] < min)
					{
						min = mat[i][j];
						in = i;
						out = j;
					}
			mat[in][out] = MAX;
			if (root[in] != root[out])
			{
				for (int i = 0;i < vex;i++)
					if (root[i] == root[out])
						root[i] = root[in];
				cout << in << " " << out << " " << min << endl;
				t--;
			}
		}
	}
	void Prim()
	{
		//布林数组final将节点分为已生成和未生成
		//初始化时,final中只有起始节点,其余节点设置为false——未生成
		//初始化结束后,进行n-1次主循环,每一次循环生成一个节点
		//每一次循环中,找出从已生成节点(final——true)到未生成节点(final——false)的最短边
		//每一次循环结束时,将该最短边的入点标为已生成节点(final——true)
		bool final[20];
		for (int i = 0;i < vex;i++)
			final[i] = false;
		final[0] = true;

		int t = vex - 1;
		while (t--)
		{
			int in, out, min;
			min = MAX;
			for (int i = 0;i < vex;i++)
				if (final[i])
				{
					for (int j = 0;j < vex;j++)
						if (!final[j] && mat[i][j] < min)
						{
							min = mat[i][j];
							in = i;
							out = j;
						}
				}
			cout << in << " " << out << " " << min << endl;
			final[out] = true;
		}
	}
	Graph(int v, int mt[20][20], char nm[20][20])
	{
		vex = v;
		for (int i = 0;i < v;i++)
			for (int j = 0;j < v;j++)
			{
				if (mt[i][j] == 0)
					mat[i][j] = MAX;
				else
					mat[i][j] = mt[i][j];
			}
		for (int i = 0;i < v;i++)
			for (int j = 0;j < v;j++)
			{
				name[i][j] = nm[i][j];
				if (nm[i][j] == '\0')
					break;
			}
	}
};
int main()
{
	int n;
	cin >> n;
	char name[20][20];
	for (int i = 0;i < n;i++)
		cin >> name[i];
	int mat[20][20];
	for (int i = 0;i < n;i++)
		for (int j = 0;j < n;j++)
			mat[i][j] = MAT[i][j];
	Graph gh(n, mat, name);
	gh.Prim();
	cout << endl;
	gh.kruskal();
	return 0;
}

 输出为(边的出点、边的入点、边的长度)

0 2 1
2 5 4
5 3 2
2 1 5
1 4 3

0 2 1
3 5 2
1 4 3
2 5 4
1 2 5
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值