图相关算法:最小生成树

  • P算法(基于点)

  • #include<iostream>
    #include<vector>
    #include<limits>
    using namespace std;
    
    int MiniSpanTree_Prim(int numVex, vector<vector<int>>arc)
    {
    	int sum = 0;
    	vector<int>adjvex(numVex);
    	vector<int>lower(numVex);
    	adjvex[0] = 0;
    	lower[0] = 0;
    	for (int i = 1; i < numVex; i++)
    	{
    		lower[i] = arc[0][i];
    	}
    	for (int i = 1; i < numVex; i++)
    	{
    		int Min = INT_MAX;
    		int j = 1;
    		int k = 0;
    		while (j < numVex)
    		{
    			if (lower[j] && lower[j] < Min)
    			{
    				Min = lower[j];
    				k = j;
    			}
    			j++;
    		}
    		sum += Min;
    		cout << adjvex[k] << " " << k << endl;
    		lower[k] = 0;
    		for (j = 0; j < numVex; j++)
    		{
    			if (lower[j] && arc[k][j] < lower[j])
    			{
    				lower[j] = arc[k][j];
    				adjvex[j] = k;
    			}
    		}
    	}
    	return sum;
    }
    int main()
    {
    	int numVex, numEdge;
    	//创建图
    	cout << "请输入图中的点数和边数:" << endl;
    	cin >> numVex >> numEdge;
    	/*cout << "请输入点的信息:" << endl;
    	vector<char>Vexs(numVex);
    	for (int i = 0; i < numVex; i++)
    	{
    		cin >> Vexs[i];
    	}*/
    	vector<vector<int>>arc(numVex, vector<int>(numVex, INT_MAX));
    	cout << "请输入边的信息(两个端点,权值):" << endl;
    	for (int i = 0; i < numEdge; i++)
    	{
    		int e1, e2, weight;
    		cin >> e1 >> e2 >> weight;
    		//无向图
    		arc[e1][e2] = weight;
    		arc[e2][e1] = weight;
    	}
    
    	//最小生成树
    	cout << "组成最小生成树的边有:" << endl;
    	int Min = MiniSpanTree_Prim(numVex, arc);
    	cout << "最小生成树的权值为:" << endl;
    	cout << Min << endl;
    	return 0;
    }

  • K算法 (基于边)

#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
struct Edge
{
	int begin;
	int end;
	int weight;
};
bool Mycom(Edge e1, Edge e2)
{
	return e1.weight < e2.weight;
}
int find(int i, vector<int>parent)
{
	while (parent[i] > 0)
	{
		i = parent[i];
	}
	return i;
}
int MiniSpanTree_K(vector<Edge>& edge, int numVex)
{
	int sum = 0;
	vector<int>parent(numVex);
	for (int i = 0; i < edge.size(); i++)
	{
		int n = find(edge[i].begin, parent);
		int m = find(edge[i].end, parent);
		if (n != m)
		{
			parent[n] = m;
			cout << edge[i].begin << " " << edge[i].end << endl;
			sum += edge[i].weight;
		}
	}
	return sum;
}
int main()
{
	int numVex, numEdge;
	cout << "请输入图中的点数和边数:" << endl;
	cin >> numVex >> numEdge;
	vector<Edge>edge(numEdge);
	cout << "请输入边的信息:" << endl;
	for (int i = 0; i < numEdge; i++)
	{
		cin >> edge[i].begin >> edge[i].end >> edge[i].weight;
	}
	sort(edge.begin(), edge.end(), Mycom);
	//最小生成树 - K算法
	cout << "组成最小生成树的边有:" << endl;
	int ret = MiniSpanTree_K(edge, numVex);
	cout << "最小生成树的权值为:" << endl;
	cout << ret << endl;

	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值