Graph theory - minimum spanning tree: Prim algorithm and optimization, comparison Kruskal's algorithm, and time complexity

Minimum spanning tree:

  Communicating a spanning tree graph with n vertices of the original image is minimal connected subgraph, and comprises all the n nodes in the original graph, and there is minimal communication while keeping FIG. Is simply and only n points n-1 edges connected graph.

  The minimum spanning tree is the minimum weight spanning tree for short, that is all right edge of the sum of the minimum spanning tree.

  Minimum spanning tree problem solving in general have the following two ways.

A, Prim algorithm

  Reference to Feynman 's blog 

  Prim's algorithm as generally adjacency matrix storage structure.

  Algorithm idea: the vertex is dominant, starting from the starting vertex, by selecting the current minimum weight edge available to them to vertex added to the spanning tree:

  1. From the communication network N = {V, E} is a vertex U 0 start, select edges (U having a minimum weight value associated with it, 0 , V), which vertex is added to the set of vertices spanning U in.

  2. After each step, while the other vertex is not in respective sides of the U is selected from a vertex in U minimum weight side (U, V), it is added to the vertices of the set U. So continue, until all the vertices of the network are added to the spanning tree vertex set U in so far. 

  Template title link: Prim minimum spanning tree algorithm

  Simple version of the time complexity of O (n²) algorithm template:

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
using namespace std;
const int N = 500+10;
int n,m;
int g[N][N],dis[N],vis[N];

void prim()
{
    memset(dis,0x1f,sizeof dis);
    dis[1]=0;
    for(int j=1;j<=n;j++)
    {
        int min_len=2e+9,k;
        for(int i=1;i<=n;i++)
        {
            if(!vis[i]&&dis[i]<min_len)
            {
                min_len=dis[i];
                k=i;
            }
        }
        vis[k]=1;
        for(int i=1;i<=n;i++)
        {
            if(!vis[i]&&dis[i]>g[k][i])
                dis[i]=g[k][i];
        }
    }

}

int main()
{
    scanf("%d%d",&n,&m);
    memset(g,0x1f,sizeof g);
    for(int i=1;i<=m;i++)
    {
        int u,v,w;scanf("%d%d%d",&u,&v,&w);
        g[u][v]=g[v][u]=min(g[u][v],w);  //因为有重边,所以取min
    }
    prim();
    int ans=0;
    for(int i=1;i<=n;i++)ans+=dis[i];
    if(ans>1e7)printf("impossible\n");
    else printf("%d\n",ans);
    return 0;
}

  Similar to Dijkstra, Prim algorithm may also be used to optimize the heap, instead of the priority queue stack, the Prim algorithm optimization time complexity of O (mlogn) template (FIG storage for star forward):

void Prim_heap(int point)
{
    memset(dis,0x1f,sizeof(dis));
    priority_queue<pair<int,int> > q;
    
    dis[point]=0;
    q.push(make_pair(0,1));
    while(!q.empty())
    {
        int k=q.top().second;
        q.pop();
        v[k]=1;
        for(int i=h[k];i!=-1;i=edge[i].next)
        {
            int to Edge = [I] .to, W = Edge [I] .W;
             IF (V [to] && DIS [to]>! W) 
            { 
                DIS [to] = W; 
                q.push (the make_pair ( , DIS [ to], to));   // priority queue large root heap becomes smaller root heap small show operation: just a '-' sign; 
            } 
        } 
    } 
    for ( int I = . 1 ; I <= n-; I ++) IF (DIS [ I] == 0x1f1f1f1f ) = In Flag to false ;   // determines whether or not the presence of the minimum spanning tree 
    return ; 
}

 

Two, Kruskal algorithm

  Compared to Prim algorithm, Kruskal still more common, reason is that a small amount of code templates and Silu Yi Kruskal's algorithm understanding.

  Algorithm ideas: a first construct containing only n vertices, edges and sub-picture set is empty, the handle of each vertex as the root FIG on each tree, then, from the right to select a set of edges E in the network the minimum value side, if two vertices belonging to different sides of the piece of tree, it is added submap, i.e. a synthesis tree the two trees, on the contrary, if the two vertices of the same strip side has fallen the tree, is not desirable, but should remove the minimum edge of a weight again. And so on, until only a forest tree, i.e. subgraph containing n-1 until the edges.

  step:

  1. FIG new G, G of the nodes have the same picture, but there is no edge;
  2. The original all sides by weight from small to large;
  3. Starting from the edge of minimum weight, if this edge connecting two nodes in a graph G not in the same connected component, then adding to this edge graph G;
  4. 3 is repeated until all nodes in G are in the same connected component.

  Is simply to position the leading edge of each selected minimum weight side, the two sides is determined whether the connected communication, if the communication, the two merged (merge operation to disjoint-set implementation). The combined number of records, when the end count equals n-1.

  Template title link: Kruskal minimum spanning tree algorithm

  Code is as follows: The time complexity of O (mlogm)

#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
using namespace std;
const int N = 100000+10, M = 200000+10; 

struct Edge{
    int u,v,w;
    bool operator < (const Edge &E)const
    {
        return w<E.w;
    }
}edge[M];
int fa[N];
int n,m,cnt,ans;

int find(int x)
{
    if(fa[x]==x)return x;
    else return fa[x]=find(fa[x]);
}

int main()
{
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++)fa[i]=i;
    for(int i=1;i<=m;i++)
    {
        int a,b,c;scanf("%d%d%d",&a,&b,&c);
        edge[i].u=a;edge[i].v=b;edge[i].w=c;
    }
    sort(edge+1,edge+m+1);
    for(int i=1;i<=m;i++)
    {
        int u=find(edge[i].u),v=find(edge[i].v),w=edge[i].w;
        if(u!=v)
        {
            cnt++;
            fa[u]=v;
            ans+=w;
        }
    }
    if(cnt==n-1)printf("%d\n",ans);
    else printf("impossible\n");
    return 0;
}

 

Three, Prim, Prim_heap, Kruskal algorithm time complexity comparison

  Reference to the G Viking 's blog

in conclusion:

  1.Prim in a dense than in FIG Kruskal preferably, in FIG sparse than Kruskal deteriorated.

  2.Prim_heap satisfactory at all times of the time complexity, but at the cost of enormous space consumption. (And code complex> _ <)

  But it is worth saying about that time complexity does not reflect the actual merits of an algorithm.

  General to competition problems are sparse graph, you can select Prim_heap; if they feel the code is too big, you want to select one of Prim and Kruskal's algorithm, then select Kruskal's algorithm.

Guess you like

Origin www.cnblogs.com/ninedream/p/11203704.html