最小生成树

Written in the front:

Sometimes we need to connect all nodes in undirected graphs at a certain cost. This is the knowledge of spanning trees. This chapter explains how to connect all nodes at a minimum cost.

difination:

Spanning Tree:

A graph without cross-cutting edges and anti-ancestor edges is a tree.

For a tree to have roots, it must have a point of zero entry.

For a graph, delete some edges to make it a tree, which is the spanning tree of the graph.

This spanning tree must be loop-free

Minimum Spanning Tree:

The spanning tree of a graph is not necessarily unique. We often need to find the smallest spanning tree (i.e. the least cost of all vertex connections).

In a given undirected graph G = ( V , E ) , G = (V, E), G=(V,E), ( u , v ) (u, v) (u,v) represents the edge (i.e., the edge) connecting the vertex u with the vertex v, and w ( u , v ) w (u, v) w(u,v) represents the weight of the edge. If there exists a subset (i.e., T) of E and it is an acyclic graph, so that w ( T ) w (T) w(T) is the smallest spanning tree of G G G, then T T T is the smallest spanning tree of G G G:
w ( T ) = ∑ ( u , v ) ∈ T w ( u , v ) w(T)=\sum_{(u,v)\in T}w(u,v) w(T)=(u,v)Tw(u,v)
It has some properties:

  • There are and only n − 1 n-1 n1edges ( n n n is the node number)

  • The minimum outgoing edge of any node must belong to MST

  • The set of ordered edge weights of any two minimum spanning trees is the same

In the following literature, the corresponding proof will be given.

Graph Segmentation:

Segmentation definition:

Divide a graph into two connected sets, and record the partition of the graph.

Graph segmentation is not necessarily unique.

Segmentation theorem:

The minimum edge connecting two connected sets must belong to MST

Adequacy proof:
  • Assuming that the theorem is not valid, there is another cross-cutting edge belonging to the minimum spanning tree.

  • Adding the shortest transverse cutting edge is bound to form a loop.

  • By deleting the original cross-cutting edge, we can get a spanning tree.

  • Notice that the only difference between the two spanning trees is the two crosscutting edges.

  • Then the weight of the spanning tree constructed subsequently is larger than the minimum spanning tree defined by us, so it is contradictory.

That is to say, proving the validity of the segmentation theorem.

Overview of Algorithms:

There are three existing minimum spanning tree algorithms: Sollin, Kruskal and prim.

Pirm Algirithm:

The core of the algorithm-the explanation of ideas:

For the original graph G = ( V , E ) G= (V,E) G=(V,E), the nodes that have been added to the minimum spanning tree are put into the set V n e w V_{new} Vnew. According to the sharding theorem: the shortest edge connecting V n e w V_{new} Vnew and its complement set must belong to the minimum spanning tree, so we can expand according to this theorem until V n e w = V V_{new}=V Vnew=V

For the sake of convenience, we remember that the node adding the minimum spanning tree is the white point, the rest nodes are the blue points, and the shortest edge of the set V n e w V_{new} Vnewis the purple edge.

Algorithm flow:

  1. Input a weighted connected graph, its edge set is E, node set is V

  2. Initialize V n e w = { x } V_{new}=\{x\} Vnew={x}, x defaults to the root node of the spanning tree. E n e w = { } E_{new}=\{\} Enew={}, an empty set

  3. Repeat until V n e w = V V_{new}=V Vnew=V

  • Find an edge ( x , y ) (x,y) (x,y), satisfying that it is the minimum edge of x x x, and x ∈ V n e w x\in V_{new} xVnew, y ∉ V n e w y ∉ V_{new} y/Vnew

  • Add node y y y to the set of V n e w V_{new} Vnew

  • Add edge ( x , y ) (x,y) (x,y) to E n e w E_{new} Enew set

  1. At the end of the algorithm, the minimum spanning tree is:
    MST = ∑ e ∈ E   new w ( e ) \texttt{MST}=\sum_{e\in \texttt{E new}}w(e) MST=eE neww(e)

A heap/line segment tree can be used to maintain the current minimum outgoing edge

Coms the code:

void prim() 
{
    for(int i = 1; i <= n; i++)
        dis[i] = inf;
    dis[1] = 0;
    Q.push((node){0, 1});
    while(!Q.empty())
    {
        node x = Q.top();
        Q.pop();
        int Purple_edge = x.w;
        int u = x.pos;
        if(!vis[u]) 
        {
            vis[u] = 1;
            MST += Purple_edge;
            for(int i = head[u]; i; i = edge[i].next)
            {
                int v = edge[i].to;
                if(dis[v] > edge[i].w)
                {
                    dis[v] = edge[i].w;
                    Q.push((node){dis[v], v});
                }
            }
        }
    }
}

Kruskal Algorithm:

Algorithm overview:

Commonly known as the additive method, it sorts all edge weights, examines each edge ( x , y ) (x, y) (x,y) in turn, and ensures that it connects two different connected components.

If it connects two different connected components, and we can be sure that it is the purple edge (which is obvious), then it can be proved that this edge must belong to the minimum spanning tree.

Algorithm flow:

  1. Rank edge weights from smallest to largest and examine all edges in turn.

  2. Initialization, V n e w , E n e w V_{new}, E_{new} Vnew,Enew as two empty sets.

  3. If the edge connected two different connected components are considered, they are added to the edge set of the minimum spanning tree

  4. When V n e w = V V_{new}=V Vnew=V, the algorithm ends

Pseudo code:

sort(E);
for: E->1 to n
{
	if: E->(x,y) Connect two connected components
	{
		put E->(x,y) to E_new;
		unionn(x, y);
	}
}

Whether two nodes belong to the same connected component can be realized by the union search set.

Union-find set:

And look up this data structure can be convenient and fast to solve this problem. The basic idea is to initially treat each object as a collection of individual elements. Then the two elements in the connected edge are merged by reading the connected edge in turn. In this process, a search operation is repeated to determine a collection within that collection. When reading in a connected edge ( x , y ) (x, y) (x,y), first judge whether x x x and y y y are in the same set, if so, do not merge; If not, then use a merge operation to merge the sets of x x x and y y y, so that any two elements in the two sets are connected. Therefore, the search and merge operations are mainly used in the processing of the union search set.

In order to facilitate the description and implementation of the union, the elements added successively to a set are usually represented as a tree structure, and the serial number of the root node is used to represent the set. So, define an array of father [ n ] \texttt{father}[n] father[n], where father [ i ] \texttt{father}[i] father[i] is the number of the parent of node i i i in the tree where i i i is. For example, if father [ 4 ] = 5 \texttt{father}[4]=5 father[4]=5, the father of node 4 4 4 is node 5 5 5. Convention: if the parent of i i i (i.e., father[I]) is a negative number, then node i i i is the root node of the set where it is, because no node in the set has a negative ordinal number. And we use the absolute value of the negative number as the number of nodes in this set. For example, if father [ 7 ] = − 4 \texttt{father}[7]=-4 father[7]=4, node 7 7 7 is the root of the set, which has four elements. The initial father value of the node is − 1 -1 1 (each node is the root and contains only one element of itself).

So,comes the code:

int find(int x) 
{
    if(father[x] == x)
        return x;
    return father[x] = find(father[x]);
}
void kruskal() 
{
    sort(edge, edge + m, cmp);
    for(int i = 0; i < m; i++) 
    {
        int u, v;
        u = find(edge[i].u);
        v = find(edge[i].v);
        if(u == v) continue;
        MST += edge[i].w;
        father[v] = u;
        if(++cnt == n - 1) break;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值