prim算法
对这种有记忆性质的变量(在外面定义,循环时会记录上次的值,类似于全局变量),每次使用都要小心,注意初始化问题!!!
using namespace std;
const int N = 6;
/*int e[N][N]={
{0,6,1,5,9999,9999},
{6,0,5,9999,3,9999},
{1,5,0,5,6,4},
{5,9999,5,0,9999,2},
{9999,3,6,9999,0,6},
{9999,9999,4,2,6,0}
}*///图,注意此图是无向图,关于对角线对称的。
int e[N][N]={
{9999,6,1,5,9999,9999},
{6,9999,5,9999,3,9999},
{1,5,9999,5,6,4},
{5,9999,5,9999,9999,2},
{9999,3,6,9999,9999,6},
{9999,9999,4,2,6,9999}
};//图,注意此图是无向图,关于对角线对称的。
int dist[N];//各点距离生成树的距离
int book[N] = {0};//标记各节点是否选入生成树;
int sum = 0;
int prim(){
for (int i = 0; i < N; ++i) {
dist[i] = e[0][i];
}
book[0] = 1;
int tmp;
int minIndex;
for (int l = 0; l < N-1; ++l) {
tmp = 99999;//第一次忘了在此处初始化tmp, tmp会记录上次运算的值,不初始化有可能在下面的循环里得不到更新minIndex的值,因此此处需要初始化。
// TODO对这种有记忆性质的变量(在外面定义,循环时会记录上次的值,类似于全局变量),每次使用都要小心,注意初始化问题!!!
for (int j = 0; j < N; ++j) {
if (tmp > dist[j] && !book[j]) {
tmp = dist[j];
minIndex = j;
}
}
book[minIndex] = 1;
sum += dist[minIndex];
for (int k = 0; k < N; ++k) {
if(!book[k]) {
// cout << dist[4] <<" " << e[1][4] <<endl;//开始的时候输入数组输错了,浪费了很多时间,以后拍错先看输入是否正确,然后考虑边界,然后考虑逻辑
if (dist[k] > e[minIndex][k]) dist[k] = e[minIndex][k];
}
}
}
return sum;
}
int main() {
cout << prim() << endl;
return 0;
}
kruskal算法
考虑清楚用并查集的意义何在!!!
#include <iostream>
#include <queue>
using namespace std;
int sum = 0;
int par[8];
void initSet(){
for (int i = 0; i < 8; ++i) {
par[i] = i;
}
}
int getPar(int a){
if(par[a] != a){
par[a] = getPar(par[a]);
}
return par[a];
}
void mergeSet(int a,int b){
par[getPar(a)] = getPar(b);
}
struct Edge{
int a,b;
int w;
Edge(){}
Edge(int x,int y,int z):a(x),b(y),w(z){}
friend bool operator < (Edge m,Edge n){
return m.w > n.w;
}
};
Edge edge[9];
priority_queue <Edge> q;
int main() {
int m,n,a,b,c;
Edge tmpEdge;
cin >> m >> n;
while (n--){
cin >> tmpEdge.a >> tmpEdge.b >> tmpEdge.w;
q.push(tmpEdge);
}
initSet();
while (!q.empty()){
tmpEdge = q.top();
q.pop();
if(getPar(tmpEdge.a) != getPar(tmpEdge.b)) {
mergeSet(tmpEdge.a,tmpEdge.b);
sum += tmpEdge.w;
}
}
cout << sum << endl;
return 0;
}