ds-消除连通图多余的边/Huffman Tree

#include<iostream>
#include<algorithm>
#define INFINITY 65535 
using namespace std;
//Prim算法
int MiniSpanTree_Prim_CostSum(int** adnj,int n) {
	int sum = 0;
	int min, i, j , k ;
	int* adjvex = new int[n];
	int* lowcost = new int[n];
	lowcost[0] = 0;
	adjvex[0] = 0;
	for (i = 1; i < n; i++) {
		lowcost[i] = adnj[0][i];
		adjvex[i] = 0;
	}
	for (i = 1; i < n; i++) {
		min = INFINITY;
		j = 1, k = 0;
		while (j < n) {
			if (lowcost[j] != 0 && lowcost[j] < min) {
				min = lowcost[j];
				k = j;
			}
			j++;
		}

		if (min != INFINITY)sum += min;

		lowcost[k] = 0;
		for (j = 1; j < n; j++) {
			if (lowcost[j] != 0 && adnj[k][j] < lowcost[j]) {
				lowcost[j] = adnj[k][j];
				adjvex[j] = k;
			}
		}
	}
	return sum;
}
//Kruskal算法
class Edge {
public:
	int begin;	//起始节点
	int end;	//终止节点
	int weight;	//权值
	Edge() {
		begin = end = weight = -1;
	}
	bool operator < (Edge& edge) {
		return weight < edge.weight;
	}
};
int find(int* parent, int f) {
	while (parent[f] > 0)f = parent[f];
	return f;
}
int MiniSpanTree_Kruskal_CostSum(int** adnj, int n, int m, Edge* edges) {
	int sum = 0;
	int i, j, k;
	int* parent = new int[n];
	sort(edges, edges+m);
	
	for (i = 0; i < n; i++)parent[i] = 0;
	for (i = 0; i < m; i++) {
		j = find(parent, edges[i].begin);
		k = find(parent, edges[i].end);
		if (j != k) {
			parent[j] = k;
			sum += edges[i].weight;
		}
	}
	return sum;
}


int main() {
	int n, m;
	cin >> n >> m;
	int** adnj;
	adnj = new int* [n];
	for (int i = 0; i < n; i++)*(adnj + i) = new int[n];
	//注意:点的编号从1开始!!!
	int sum = 0;
	for (int i = 0; i < n; i++) {
		for (int j = 0; j < n; j++) adnj[i][j] = INFINITY;
	}
	
	Edge* edges = new Edge[m];//用于Kruskal算法

	for (int i = 0; i < m; i++) {
		int vex1,vex2,cost;
		cin >> vex1>> vex2 >> cost;
		adnj[vex1 - 1][vex2 - 1] = cost;
		adnj[vex2 - 1][vex1 - 1] = cost;
		
		edges[i].begin = vex1 - 1;
		edges[i].end = vex2 - 1;
		edges[i].weight = cost;

		sum += cost;
	}
	
	
	int res1 = sum - MiniSpanTree_Prim_CostSum(adnj, n);
	int res2 = sum - MiniSpanTree_Kruskal_CostSum(adnj, n, m, edges);
	cout << res1 << " " << res2 ;

	return 0;
}

分别通过Prim和Kruskal算法实现 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值