Thorough understanding of kruskal algorithm (including union search and minimum spanning tree explanation)

//If you have any questions, please leave a message
. The kruskal algorithm is usually used to find the minimum spanning tree in a connected graph. This article will discuss this algorithm and the basis of the algorithm (minimum spanning tree, union search) Detailed introduction.

minimum spanning tree

First of all, let's clarify the concept. What is the minimum spanning tree?
Now I have a connected graph composed of n nodes (below),

you can see that each node has many edges connected to other nodes, we want to make this graph into a minimum spanning tree, we only need to make each node At least one edge is connected to other points, and the edge weight of each point is certain. We need to delete some edges while ensuring the connectivity of the graph, so that the edge weights of the remaining edges are as close as possible. Small, the last image left will be the minimum spanning tree of the original image (as shown below).
minimum spanning tree
see it? The current graph deletes useless edges, and makes the sum of edge weights the smallest while ensuring that each point in the graph is directly or indirectly connected, which is the minimum spanning tree.
It should be emphasized that the number of edges in the minimum spanning tree is equal to the number of points - 1.

and check

So the question is, how do we judge whether two points are connected?
At this time, you need to use and check the set.

general idea

Initialize each point and set their parent to itself. When you need to merge two points (or sets), you only need to modify their parents so that one point is the parent of all points in this set. If the two point parents If they are the same, it means they are in a set.

Example

To give an easy-to-understand example, there is a group of people who do not necessarily know each other, so how do they distinguish which gang they belong to? When A sees B, he only needs to say that his captain is XXX, and B says his captain is XXX. If the captains are the same, they belong to the same team. When the two teams need to merge, they choose a captain, and then let the two teams be in the same team. All of you know the captain, so when you meet someone else, you can report the name of the captain to determine whether you belong to the same team as the other party.

kruskal kruskal

Now that we have the accumulation of basic knowledge, let's get to the point. How does the kruskal algorithm find the minimum spanning tree of a graph?

Algorithm Analysis

Sort all the edges according to their edge weights from small to large, and then perform a traversal to enumerate each edge. If the two points connected by the edge have not been connected, select this edge to construct the minimum spanning tree, If the connection is passed, ignore it and continue to enumerate the next edge until the enumeration is completed, and all the selected edges constitute the minimum spanning tree.

principle

Because the edges are sorted from small to large, the edge considered first must have a smaller edge weight than the edge considered later, so if two points are connected in two ways, the way to enumerate first must be higher than that of later enumeration The way to reach is better, so there is no need to consider which of the many ways to link two points is the optimal solution.

illustrate

First, we assume that all edges do not exist, which is represented by a dotted line:
01
then we enumerate whether each edge is selected in order from small to large. The points at both ends of the first edge are not in a set, so connect them:
02
then turn the edges in turn The four sides with weights 3, 4, and 5 are selected (all meet the selection conditions)

03
04
05
At this time, let's consider the edge with the edge weight of 6, and find that the points at both ends of it have been connected together, so we do not select the edge with the edge weight of 6, and use blue to indicate that we do not select it.
06
Similarly, the last edge is not selected
07
so that we get the minimum spanning tree of the original graph.
In fact, kruskal is a combination of union search and greed. It is not difficult to understand if you look at the graph carefully.

Fake code
按边权排序;
for(int i=1;i<=边数;i++)
{
    if(两个点父亲相同) continue;
    else{
    选取的边[++cnt]=这条边;
    使两条边父亲相同;
    }
}

If you are still not clear, look at the code.

Program implementation
//by floatiy
#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
int n,cnt,num,ans,m;//n为点的数量,m是边的总数,num是已经选取了的边数 
int fa[105];//存储每个点的父亲 
struct Edge{
    int w;//边权 
    int to,pre;//边相连的两个点 
};
Edge len[1000];//结构体存储更方便调用 
bool cmp(Edge x,Edge y)//使sort按照边权大小排序 
{
    return x.w < y.w;
}
int find(int x)//并查集 找父亲的函数
//注意这里使用的是递归查找,可以让这个点(A)的父亲也认A的祖先做父亲,使得一次递归经过的所有点的父亲都变成祖先,大大降低了时间复杂度。 
{
    if(fa[x]==x) return x;
    return fa[x]=find(fa[x]);
}
void build(int x)//选取函数,答案加上边权值,然后两个点相连 
{
    ans+=len[x].w;
    fa[find(len[x].pre)]=find(len[x].to);
    return;
}
int main()
{
    int x,y,we;//两个点和边权 
    cin>>n>>m;//n个点 m个边  
    for(int i=1;i<=m;i++)
    {
        cin>>x>>y>>we;
        len[i].to=x;
        len[i].pre=y;
        len[i].w=we;
    }
    sort(len+1,len+m+1,cmp);//按边权排序 
    for(int i=1;i<=n;i++) fa[i]=i;//重点!必须事先把每个点的父亲赋值为它自己,不然默认每个点父亲都是0,会出错。 
    for(int i=1;i<=m;i++)//按边权从小到大枚举 
    {
        if(num==n-1) break;//如果选取的边足够了,就停止循环 
        if(find(len[i].pre)==find(len[i].to)) continue;//如果两个点的父亲相同(已经合并了),就不管它了 
        else{
            build(i);
            num++;//已经选取的边数+1 
        }
    }
    printf("%d",ans);
    return 0;
}

Let's take a look at the running results (using the image of the previous example as data)

Recommended topics

Knowledge needs to be consolidated. I recommend a few kruskal naked questions that are very suitable for beginners:
USACO Shortest Network Agri-Net (luogu1546)
Local Area Network (luogu2820)
Wireless Communication Network (luogu1991, this question is slightly difficult)

Guess you like

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