The basic minimum spanning tree algorithm

  • Prim's algorithm

Prim minimum spanning tree algorithm to find the feeling of a process like dp course, just a point from the beginning, every time find local optimal solution, and finally you can find all the entire minimum spanning tree.

const int MAXN = 1000;
const int LIM = 0x3f3f3f3f;

struct MGraph
{
  int vexs[MAXN];//顶点表
  int arc[MAXN][MAXN];//邻接矩阵
  int numEdges, numVertexes;//边,点的数量
};

void MiniSpanTree(MGraph G)
{
  int adjvex[MAXN];
  int lowcost[MAXN];//储存每一次延伸后的最小权值
  adjvex[0] = 0;
  lowcost[MAXN] = 0;//置0代表该点已经加入最小生成树,这里就把0这个点作为起始点
  for (int i = 1; i < G.numVertexes; i++)//初始化第一个点延伸出去的边信息
  {
      lowcost[i] = G.arc[0][i];
      adjvex[i] = 0;
  }
  for (int i = 1; i < G.numVertexes; i++)
  {
      int mmin = LIM;
      int k;
      for (int j = 1; j < G.numVertexes; j++)//找到lowcost中的最小边
      {
          if (lowcost[j] != 0 && mmin > lowcost[j])
          {
              mmin = lowcost[j];
              k = j;
          }
      }
      cout << '(' << adjvex[k] << ',' << k << ')' << endl;//打印最小生成树的边
      lowcost[k] = 0;//把该顶点置0
      for (int j = 1; j < G.numVertexes; j++)//把下一个顶点的边加入lowcost
      {
          if (lowcost[j] != 0 && G.arc[k][j] < lowcost[j])
          {
              lowcost[j] = G.arc[k][j];//更新lowcost
              adjvex[j] = k;//找到该点的上一个顶点
          }
      }
  }
}
  • Kruskal's algorithm

This process of algorithm is a set of division, and to ensure the collection of which will not form a loop. Because the array has the edge set in advance from small to large order, so every time added to the collection can be considered the rest of the optimal solution.

#include<iostream>
#include<algorithm>
using namespace std;

const int MAXN = 1000;

struct Edge//边集数组
{
    int begin;
    int end;
    int weight;
};

struct Graph//图
{
    Edge edges[MAXN];
    int numVertexes,numEdges;
};

bool cmp(Edge a,Edge b)//定义比较函数,从小到大排序
{
    return a.weight<b.weight;
}

void MiniSpanTree(Graph G)
{
    sort(G.edges,G.edges+G.numEdges,cmp);//将边从小到大排序
    int parent[MAXN];//判断是否形成了环路
    for(int i=0;i<G.numVertexes;i++)
    {
        parent[i]=0;//初始化数组
    }
    for(int i=0;i<G.numVertexes;i++)
    {
        int n = Find(parent,G.edges[i].begin);
        int m = Find(parent,G.edges[i].end);
        if(m!=n)//如果不是环路,即一个顶点不在已经划定的集合里面
        {
            parent[n] = m;//加入集合
            cout<<'('<<G.edges[i].begin<<','<<G.edges[i].end<<' '<<G.edges[i].weight<<endl;//输出
        }
    }
}

int Find(int *parent,int f)//找到集合的末尾,便于找两个点是否都在一个集合里面
{
    while(parent[f])
        f = parent[f];
    return f;
}

Guess you like

Origin www.cnblogs.com/JMWan233/p/11485722.html