zoukankan      html  css  js  c++  java
  • 最小生成树K氏法

    K氏法

    K氏法也叫Kruskal算法,是将各边按照权值从小到大排列,接着从权值最低的边开始建立最小成本生成树,如果加入的边造成了贿赂,则舍弃不用,直到加入n-1个边为止。

    示例

                                                    

     

            把所有边的成本列出,按照从小到大排列。

    起始 终止 成本
    B C 3
    B D 5
    A B 6
    C D 7
    B F 8
    D E 9
    A E 10
    D F 11
    A F 12
    E F 16

            1.选择成本最低的一条边作为建立最小成本生成树的起点。

                                    B----C   3

            2.按照建立的表格,按序加入边

                                    B-----C  3                 B----D 5

            直到完成所有的生成树,结果为:

                                  

                    代码:                           

        public class Node
        {
            const int MAXLENGTH = 20;   //链表的最大长度
            public int[] from = new int[MAXLENGTH];
            public int[] to = new int[MAXLENGTH];
            public int[] find = new int[MAXLENGTH];
            public int[] val = new int[MAXLENGTH];
    
            public int[] next = new int[MAXLENGTH];   //链表的一个节点位置
    
            public Node()
            {
                for(int i = 0; i < MAXLENGTH; i++)
                {
                    next[i] = -2;   //-2表示未用节点
                }
            }
    
            //查找可用节点
            public int FindFree()
            {
                int i;
                for(i = 0; i < MAXLENGTH; i++)
                {
                    if (next[i] == -2)
                        break;
                }
                return i;
            }
            //建立链表
            public void Create(int header,int freeNode,int dataNum,int fromNum,int toNum,int findNum)
            {
                int point;   //现在的节点位置
                if (header == freeNode)     //新的链表
                {
                    val[header] = dataNum;    //设置数据编号
                    from[header] = fromNum;
                    find[header] = findNum;
                    to[header] = toNum;
                    next[header] = -1;    //将下个节点的位置 ,-1表示空节点
                }
                else
                {
                    point = header;
                    val[freeNode] = dataNum;
                    from[freeNode] = fromNum;
                    find[freeNode] = findNum;
                    to[freeNode] = toNum;
    
                    //设置数据名称
                    next[freeNode] = -1;
                    //寻找链表的尾端
                    while (next[point] != -1)
                    {
                        point = next[point];
                    }
                    //将新节点串联在原链表的尾端
                    next[point] = freeNode;
                }
            }
    
            public void Print(int header)
            {
                int point;
                point = header;
                while (point != -1)
                {
                    Console.Write($"起始顶点 [{from[point]}]   终止顶点[");
                    Console.Write($"{to[point]} ]   路径长度[{val[point]}]");
                    Console.WriteLine();
                    point = next[point];
                }
            }
        }

                       

    class Program
        {
            static int verts = 6;
            static int[] v = new int[verts + 1];
            static Node newlist = new Node();
    
            static void Main(string[] args)
            {
                int[,] data = { { 1, 2, 6 }, { 1, 6, 12 }, { 1, 5, 10 }, { 2, 3, 3 }, { 2, 4, 5 }, { 2, 6, 8 }, { 3, 4, 7 }, { 4, 6, 11 }, { 4, 5, 9 }, { 5, 6, 16 } };
                int dataNum;
                int fromNum;
                int toNum;
                int findNum;
                int header = 0;
                int freeNode;
                for(int i = 0; i < 10; i++)
                {
                    for(int j = 1; j <= verts; j++)
                    {
                        if (data[i, 0] == j)
                        {
                            fromNum = data[i, 0];
                            toNum = data[i, 1];
                            dataNum = data[i, 2];
                            findNum = 0;
                            freeNode = newlist.FindFree();
                            newlist.Create(header, freeNode, dataNum, fromNum, toNum, findNum);
                        }
                    }
                }
                newlist.Print(header);
                Console.WriteLine("建立最小成本的生成树:");
                MinTree();
    
                Console.ReadLine();
            }
    
            //找出剩下最小的
            static int FindMinCost()
            {
                int minVal = 100;
                int retPtr = 0;
                int a = 0;
    
                while (newlist.next[a] != -1)
                {
                    if (newlist.val[a] < minVal && newlist.find[a] == 0)
                    {
                        minVal = newlist.val[a];
                        retPtr = a;
                    }
                    a++;
                }
                newlist.find[retPtr] = 1;
                return retPtr;
            }
    
            static void MinTree()
            {
                int result = 0;
                int mcePtr;
                int a = 0;
                for(int i = 0; i <= verts; i++)
                {
                    v[i] = 0;
                }
                while (newlist.next[a] != -1)   //next表示的是有几条边
                {
                    mcePtr = FindMinCost();
                    v[newlist.from[mcePtr]]++;
                    v[newlist.to[mcePtr]]++;
                    if (v[newlist.from[mcePtr]] > 1 && v[newlist.to[mcePtr]] > 1)
                    {
                        v[newlist.from[mcePtr]]--;
                        v[newlist.to[mcePtr]]--;
                        result = 1;
                    }
                    else
                        result = 0;
    
                    if (result == 0)
                    {
                        Console.Write($"起始顶点[{newlist.from[mcePtr]}]  终止顶点[{newlist.to[mcePtr]}]  路径长度[{newlist.val[mcePtr]}");
                        Console.WriteLine();
                    }
                    a++;
                }
            }
        }
  • 相关阅读:
    html 3
    html标签2
    html标签
    2017.4.27
    2017.4.26
    2017.4.25
    2017.4.20
    2017.1.18
    2017.4.17
    2017.4.16.
  • 原文地址:https://www.cnblogs.com/xiaowangzi1987/p/15193726.html
Copyright © 2011-2022 走看看