DS图—最小生成树
题目描述
根据输入创建无向网。分别用Prim算法和Kruskal算法构建最小生成树。(假设:输入数据的最小生成树唯一。)
输入
顶点数n
n个顶点
边数m
m条边信息,格式为:顶点1顶点2权值
Prim算法的起点v
输出
输出最小生成树的权值之和
对两种算法,按树的生长顺序,输出边信息(Kruskal中边顶点按数组序号升序输出)
输入样例:
6
v1 v2 v3 v4 v5 v6
10
v1 v2 6
v1 v3 1
v1 v4 5
v2 v3 5
v2 v5 3
v3 v4 5
v3 v5 6
v3 v6 4
v4 v6 2
v5 v6 6
v1
输出样例:
15
prim:
v1 v3 1
v3 v6 4
v6 v4 2
v3 v2 5
v2 v5 3
kruskal:
v1 v3 1
v4 v6 2
v2 v5 3
v3 v6 4
v2 v3 5
参考代码:
#include <iostream>
using namespace std;
#define MAX_WEIGHT 99999
struct {
string adjvex;
int weight;
} Close_Edge[100];
class MGraph {
int Graph_Prim[100][100], Graph_Kruskal[100][100];
int n, nedge;
int visited[100];
string *node;
string start;
int startpos;
public:
MGraph() {}
void SetMGraph() {
int i, j;
cin >> n;
for (i = 0; i < n; i++)
for (j = 0; j < n; j++) {
Graph_Prim[i][j] = 10000;
Graph_Kruskal[i][j] = 10000;
}
node = new string[n];
for (i = 0; i < n; i++)
cin >> node[i];
cin >> nedge;
for (i = 1; i <= nedge; i++) {
string ch1, ch2;
int weight_;
cin >> ch1 >> ch2 >> weight_;
int loc1, loc2;
for (j = 0; j < n; j++) {
if (node[j] == ch1)
loc1 = j;
if (node[j] == ch2)
loc2 = j;
}
Graph_Kruskal[loc1][loc2] = Graph_Prim[loc1][loc2] = weight_;
Graph_Kruskal[loc1][loc2] = Graph_Prim[loc2][loc1] = weight_;
}
cin >> start;
for (i = 0; i < n; i++)
if (node[i] == start)
startpos = i;
}
void Prim() {
int i, j;
for (i = 1; i <= n; i++)
visited[i] = 0;
visited[startpos] = 1;
int min_;
for (i = 0; i < n; i++) {
min_ = MAX_WEIGHT;
for (j = 0; j < n; j++)
if (Graph_Prim[i][j] < min_) {
min_ = Graph_Prim[i][j];
Close_Edge[i].adjvex = node[j];
Close_Edge[i].weight = min_;
}
}
string s3;
string *e1, *e2;
int *w3;
e1 = new string[100];
e2 = new string[100];
w3 = new int[100];
int index, k = 0;
for (i = 0; i < n; i++) {
min_ = MAX_WEIGHT;
for (j = 0; j < n; j++) {
if (!visited[j])
continue;
else {
if (min_ > Close_Edge[j].weight) {
min_ = Close_Edge[j].weight;
s3 = Close_Edge[j].adjvex;
index = j;
}
}
}
e1[k] = node[index];
e2[k] = s3;
w3[k++] = min_;
for (int g = 0; g < n; g++) {
if (node[g] == s3) {
visited[g] = 1;
break;
}
}
for (int g = 0; g < n; g++) {
min_ = MAX_WEIGHT;
for (int m = 0; m < n; m++) {
if (min_ > Graph_Prim[g][m] && visited[m] == 0) {
min_ = Graph_Prim[g][m];
Close_Edge[g].adjvex = node[m];
Close_Edge[g].weight = min_;
}
}
}
}
int Weight = 0;
for (i = 0; i < k - 1; i++) {
Weight += w3[i];
}
cout << Weight << endl;
cout << "prim:" << endl;
for (i = 0; i < k - 1; i++)
cout << e1[i] << " " << e2[i] << " " << w3[i] << endl;
}
void Kruskal() {
int i, k, j;
cout << "kruskal:" << endl;
int *uni = new int[n];
for (i = 0; i < n; i++)
uni[i] = i;
for (i = 0; i < n - 1; i++) {
int min = MAX_WEIGHT;
int x, y;
for (j = 0; j < n; j++)
for (k = 0; k < n; k++) {
if (j == k)
continue;
if (uni[j] == uni[k])
continue;
else {
if (min > Graph_Kruskal[j][k]) {
min = Graph_Kruskal[j][k];
x = j;
y = k;
}
}
}
Graph_Kruskal[x][y] = MAX_WEIGHT;
Graph_Kruskal[y][x] = MAX_WEIGHT;
if (x > y)
swap(x, y);
for (j = 0; j < n; j++) {
if (uni[j] == uni[y] && j != y)
uni[j] = uni[x];
}
uni[y] = uni[x];
cout << node[x] << " " << node[y] << " " << min << endl;
}
}
};
int main() {
MGraph m, M;
m.SetMGraph();
m.Prim();
m.Kruskal();
return 0;
}