About minimum spanning tree

table of Contents


Minimum spanning tree

\ (By: Fields \)

  • Definition: An \ (n-\) spanning FIG communication nodes are connected subgraph minimal original image, and contains all the original \ (n-\) nodes, and holding FIG communication minimal side. The minimum spanning tree can be \ (Kruskal \) algorithm or \ (Prim \) algorithm derived.

Kruskal

  • Definitions: \ (Kruskal \) is based on the idea of get greedy.
    First, we put all the edges according to weight in ascending order, then the order of selecting each edge, if the two end points of this edge does not belong to the same set, then they will be combined, until all the points are in the same the collection so far. See here, we can think of another algorithm - disjoint-set, put it plainly, \ (Kruskal \) algorithm is based on and check the greedy algorithm sets.

  • Time complexity: \ (O (MlogM) \) \ (M \) is the total number of edges in the graph.
  • The basic idea: \ (Kruskal \) is a side-dominant position, always choose the right edge of the smallest side currently available, each time selecting the right edge of the smallest edge connector, to determine there is no communication between the two endpoints.

Code is as follows :( thanks gyh Gangster "sponsorship")

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

struct edge
{
    int u,v,w;//分存每一条边前,后坐标与权值 
}a[3000010];

int n,m,num;//存边的数量 
int pre[1000010];//存并查集中的祖先 

bool cmp(edge aa,edge bb)
{
    return aa.w<bb.w;
}//结构体sort排序必须自定义排序函数 

void add(int u,int v,int w)
{
    a[++num].u=u;
    a[num].v=v;
    a[num].w=w;
}

int find(int x)
{
    return pre[x]==x?x:pre[x]=find(pre[x]);
}

void join(int x,int y)//并集 
{
    int r1=find(x),r2=find(y);
    if(r1!=r2) 
    {
        pre[r1]=r2;
    }
}

signed main()
{
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++) 
    {
        pre[i]=i;//重置先祖 
    }
    for(int j=1;j<=m;j++)
    {
        int u,v,w;
        scanf("%d%d%d",&u,&v,&w);//输入各边权值 
        add(u,v,w);
    }
    sort(a+1,a+num+1,cmp);
    int sum=0;
    for(int i=1,tot=0;i<=num&&tot!=n;i++)
    {
        if(find(a[i].u)==find(a[i].v)) 
        {
            continue;
        }
        join(a[i].u,a[i].v);
        ++tot;
        sum+=a[i].w;
    }
    printf("%d",sum);//输出 
    return 0;
}

Here publicity about gyh Gangster blog

Guess you like

Origin www.cnblogs.com/Soroak/p/11700988.html