最小生成树 kruskal算法 归纳

来源:互联网 发布:中金云金融大数据公司 编辑:程序博客网 时间:2024/04/29 22:22

还是来自于李春葆的"数据结构"一书,自己尽量将模板写简洁了一点

算法过程:将边按照从小到大排列,依次加入最小边,如果加入这条边不形成回路(使用并查集,不在同一个集合的两个顶点就不会形成回路),就加入这条边,直到加入n-1条边为止.

#define MAXV 100//后面都会用到#define MAXSIZE (100*100)#define INF 100000//INF表示正无穷struct MGraph{    int edges[MAXV][MAXV];//邻接矩阵的边数组    int n;//顶点数,弧度;};MGraph g;int sum;//并查集int Father[MAXV]; // Father[i] 表示 i 的父节点int FindSet(int x){    while (x != Father[x]) x = Father[x];    return x;}//边struct Edge{    int p1,p2;    int val;};bool cmp(Edge a,Edge b){    return a.val < b.val;//按照边从小到大排序}void Kruskal(MGraph g){    Edge e[MAXSIZE];//边数组    int i,j,k=0;    //对边进行排序    for(i=0;i<g.n;i++)    for(j=0;j<g.n;j++)       if(g.edges[i][j]!=0 && g.edges[i][j]!=INF)       {           e[k].p1=i; e[k].p2=j; e[k].val=g.edges[i][j];           k++;       }    sort(e,e+k,cmp);    //初始化并查集    for(i=0;i<g.n;i++) Father[i]=i;    //处理    k=1; j=1;    while(k<g.n)    {        int f1=FindSet(e[j].p1), f2=FindSet(e[j].p2);        if(f1!=f2)        {            k++; sum +=e[j].val;             Father[f1]=f2;//并查集合并        }        j++;    }}