一.kruskal
#include <iostream>
#include <vector>
#include <string.h>
#include <string>
#include <algorithm>
#include <cmath>
# define N 1000
using namespace std;
struct Graph{
int u, v, cost; // 顶点u, v, 边的权重是cost
void set(int a, int b, int w){
u = a;
v = b;
cost = w;
}
};
Graph graph[N * (N + 1) / 2]; // 顶点数n,边的数量是 <= n * (n+1) / 2
void intiGraph(int m){
int i;
int v, w, edge;
for(i = 0;i < m;i++){
cin >> v >> w >> edge;
graph[i].set(v,w,edge);
}
}
// 升序
int cmp(Graph x, Graph y){
if (x.cost < y.cost) return true;
return false;
}
// 找祖先,观察是否是一个树
int father[N]; // 表示N的父亲的编号
int find(int x){
if(father[x] == -1) return x;
return father[x] = find(father[x]); // x的父亲是找x的父亲
}
bool Union(int x, int y){
// 看两个结点的祖先是否相同
x = find(x);
y = find(y);
// 是一个祖先
if(x == y) return false;
// 不是一个祖先,合并
if(x > y) father[x] = y;
if(y > x) father[y] = x;
return true;
}
// kruskal算法
void Kruskal(int e){
memset(father, -1, sizeof(father));
int sum = 0; // 最小树的权值和
int count = 0; // 已经找到的边数,直到n-1
cout << "答案是:" << endl;
for(int i = 0; i < e; i++){
// 找到满足的边
if(Union(graph[i].u, graph[i].v)) { // 如果第i条边的u,v能合成一棵树(他们两个原来不是一个树)
cout << graph[i].u << " " << graph[i].v << endl;
sum += graph[i].cost;
++count;
}
// if(count == n-1) break;
}
cout << sum << endl;
}
int main(){
int e;
cout << "边的数量是" << endl;
cin >> e;
intiGraph(e);
sort(graph, graph+e, cmp);
Kruskal(e);
}
input
1 3 1
4 6 2
2 5 3
3 6 4
1 4 5
2 3 5
3 4 5
1 2 6
3 5 6
5 6 6
二.prim
#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
#include <cmath>
#define MAX 100
#define MAXCOST 0x7fffffff
using namespace std;
int graph[MAX][MAX];
int prim(int graph[][MAX], int n)
{
int lowcost[MAX];
int mst[MAX];
int i, j, min, minid, sum = 0;
for (i = 2; i <= n; i++)
{
lowcost[i] = graph[1][i];
mst[i] = 1; //mst[]存放MST外的点i到MST最短距离时候对应的MST里的点标号
}
mst[1] = 0;
for (i = 2; i <= n; i++) //要找出n-1个点为止
{
min = MAXCOST;
minid = 0;
for (j = 2; j <= n; j++)
{
if (lowcost[j] < min && lowcost[j] != 0)
{
min = lowcost[j];
minid = j;
}
}
cout << minid << endl;
cout << "V" << mst[minid] << "-V" << minid << "=" << min << endl;
sum += min;
lowcost[minid] = 0; // 使minid成为内部点
// 更新内部点到外部点的最小距离的候选点,j是候选点,mst[j]表示与外部点j连结距离最小的内部点
for (j = 2; j <= n; j++)
{
if (graph[minid][j] < lowcost[j]) //不更新的话,lowcost[j]存的只是上一时刻的Lowcost[j],MST外部的点到minid的距离会不会比到之前的MST里点得最小距离小?
{
lowcost[j] = graph[minid][j]; // 更新外部点到内部点的最小距离
mst[j] = minid; //点j到MST内的lowcot对应的MST里的点事minid
cout << j << " ";
cout << "mst[j] " << mst[j] << " ";
cout << "lowcost[j]" << lowcost[j] << " ";
cout << endl;
}
}
}
return sum;
}
int main()
{
int i, j, k, m, n;
int x, y, cost;
cin >> m >> n;//m=顶点的个数,n=边的个数
//初始化图G
for (i = 1; i <= m; i++)
{
for (j = 1; j <= m; j++)
{
graph[i][j] = MAXCOST;
}
}
//构建图G
for (k = 1; k <= n; k++)
{
cin >> i >> j >> cost;
graph[i][j] = cost;
graph[j][i] = cost;
}
//求解最小生成树
cost = prim(graph, m);
//输出最小权值和
cout << "最小权值和=" << cost << endl;
system("pause");
return 0;
}