Learning Graph Theory (5) - Minimum Spanning Tree

1. Concept
Spanning tree: A spanning tree of a connected graph refers to a subgraph of the graph, which contains all vertices (N) of the graph, but only has enough N-1 edges to connect all vertices together. If you add another edge to it, there must be a ring.
Minimum spanning tree: Among all the spanning trees of a connected graph, the spanning tree with the smallest sum of the weights of all edges is called the minimum spanning tree.

2. Practical application
When learning a structure or an algorithm, I often consider which aspects it is related to in real life and whether it can be applied to real life. Not just know the solution that can be used as a problem.
In practice, the minimum spanning tree can be used for the calculation of the laying of communication networks and the calculation of roads between cities. The data I have found are generally based on cost. That is to use the knowledge of minimum spanning tree, consider how to build the most cost-effective and can be put into practice.

Three, two algorithms

  1. Kruskal (Kruskal) algorithm
    learning reference blog ( https://blog.csdn.net/luomingjun12315/article/details/47700237 )
    Thought:
    1. Sort all edges in the graph in ascending order of cost;
    2. Treat the n vertices in the graph as a forest of independent n trees;
    3. Select edges from small to large, and the selected edges connect two vertices u , v .
      u , v , should belong to two different trees, it becomes an edge of the minimum spanning tree, and the two trees are merged into one tree.
    4. Repeat (3) until all vertices are in a tree or there are n-1 edges.

In their own words:
first sort the lengths of each edge from small to large;
then search for the sorted edges in turn;
if the two ends of the searched edges are not in one set, merge the two sets;
that is, the two ends If they are not in the same connected graph, that is, merge the graphs where the two points are located;
until all the points are in the same set (the same graph), you can.

Because each time it selects the smallest edge that can be connected to the points in the set of minimum spanning tree points, the final sum of edge weights is the smallest.

struct edge
{
    //u v 为边的前后节点
    int u;
    int v;
    int w;//权重
} e[MAXN];
bool comp(const int a,const int b)
{
    //间接比较,实现对边权大小的排序
    return e[a].w<e[b].w;
}
int find(int x)
{
    int t = x;
    while(t!=pre[t])
        t=pre[t];  //找到根结点
    int i=x,j;
    //优化步骤,让所有子节点都直接与父节点相连,使每次搜索父节点的效率提高很多
    if(pre[i]!=t)//
        while(t!=i)//压缩路径,将树的深度变成只有 2,即所有叶都直接连在同一根上
        {
            j=pre[i];
            pre[i]=t;
            i=j;
        }
    return t;
}
int Kruscal()
{
    int ans=0;
    for(int i=1;i<=n;++i)
        pre[i] = i; //每个点的父节点一开始都是它本身,因为此时每个点占了一个集合 
    for(int i=1;i<=m;++i) // r[]数组存放的是边的序号 
        sort(r,r+m,comp); //对边的权值从小到大进行排序 
    for(int i=1; i<=m; ++i)
    {
        int x=find(e[r[i]].u);
        int y=find(e[r[i]].v);
        if(x!=y)//两个点不在同一个集合,则合并
        {
            //根节点相连
            pre[x]=y;  //将其中一个设置为另外一个的父节点,则连接了两个集合
            ans+=e[r[i]].w;
        }
    }
    return ans;  //最小总权值
}

The idea of ​​union and search is used in it.
(Learning reference blog: https://blog.csdn.net/luomingjun12315/article/details/47373345 )
And check set : It is a data structure used to manage grouping, it can query whether two elements a and b are the same The elements of a set, if not and if necessary, combine a and b into the same set.
In the minimum spanning tree, each connected component can be regarded as a set that contains all the points in the connected component. These points are connected to each other, and there is no order of precedence, just like the elements in a set, only the difference between "belongs to" and "does not belong to".
In the find function of the above code, a loop is used to optimize the union search, so that the child nodes are directly connected to the parent node, which greatly improves the search efficiency.

2. Prime (Prime) algorithm
learning reference blog ( https://blog.csdn.net/lqcsp/article/details/14118871 )
Thought: In a weighted connected graph V is a set containing all vertices, U is already in The set of nodes in the minimum spanning tree, starting from any vertex v in the graph, at this time the set U={v}, repeat the following operations: on all edges (u, v) of u ∈ U, v ∈ VU Find an edge with the smallest weight in ∈E, add the edge (u, w) to the set of found edges, and add the point w to the set U, when U=V, the smallest edge is found. spanning tree.

I personally think it is similar to Kruskal's algorithm. The Kruskal algorithm focuses on edges. After sorting all edges, it traverses the edges. The worst case may be traversed to the end. The efficiency of use in sparse graphs is good, but the efficiency of dense graphs may not be very high. The Prime algorithm focuses on points, and finds edges based on points, which is better than Kruskal's algorithm when used in dense graphs.

//任意选择一个起点 u
//每次把点添加到最小生成树点的集合U中,都把添加进去的点跟集合内其他点的距离设置为0,表示在集合中
int Prime(int u)
{
    for (int i = 1; i <= n; i++)
        dis[i] = (i==u?0:g[u][i]); //dis[i] 表示是的 节点 i 到集合U的最短距离
//N-1次遍历,每次都从集合N中找到一个结点,距离集合Y中所有结点值最小
    for (int i = 1; i < n; i++)
    {
        int temp=INF,k;
        for (int j = 0; j < n; j++)
            //找一条到集合U的最小的边
            if(!dis[j]&&dis[j]<temp )
            {
                temp = dis[j];
                k = j;
            }
        ans+=temp;
        dis[k] = 0;//将节点加入到 U(最小生成树点集)中
        //更新N集合中剩余的其他结点,因为dis[k]发生了变化
        for (int j=0; j<n; j++)
            if(dis[j] > g[j][k])
                dis[j] = g[j][k];
    }
    return ans;//最小总权值
}

First learn these two basic ones, which are more commonly used, and some optimization methods will be studied in depth later.
If the reader has an optimized method for the above code, please advise.

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324379654&siteId=291194637