• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            yuanyuelang

            常用鏈接

            統計

            最新評論

            最小生成樹之Kruskal算法

            最小生成樹是圖論的一個重要部分,解決這個問題的算法主要有Kruskal算法和Prim算法。

            最小生成樹:顧名思義是一棵樹,該樹是圖中權值和最小的。

            我們先來介紹Kruskal算法,Prim算法請參閱最小生成樹之Prim算法

            該算法的基本思路:貪心,如何貪心呢?
            它的貪心準則是:
            1.每次從剩下的邊中選擇一個不會產生環路而且權值最小的邊加入到已經選擇好的邊的集合中。
            2.它需要e步的操作,e表示圖的邊數,我們可以按權值排好序后,對每一條邊進行選擇,如果加入到已經選擇好的邊中會產生回路的現象,就不要了。。。否則加入到已經選擇好的邊中。
            3.我們還需用到并查集的思想,有關并查集的介紹,請查看我的另一篇博文 不相交集合數據結構
            4.復雜度:O(ElgE),其中E為圖的邊數

            接下來我們引用POJ上的一個經典題目來分析,題目網址http://acm.pku.edu.cn/JudgeOnline/problem?id=1861

            題目大意是:題目給出的是圖的頂點和所有邊的集合,要求輸出的是最小生成樹的邊

            我們來看下源碼啦:
            #include<iostream>
            using namespace std;
            #include
            <algorithm>
            #include 
            <memory.h>

            #define MAXEDGE 15001//最大邊數
            #define MAXNODE 1001 //最大節點數

            int p[MAXNODE],rank[MAXNODE];//用于不相交集合
            int start[MAXEDGE],end[MAXEDGE],weight[MAXEDGE],VNum,ENum;//分別為邊的起點,終點,權重,節點數和邊數
            int result_s[MAXEDGE],result_e[MAXEDGE];//分別為存儲最小生成樹的起點,終點
            int max_weight,id[MAXEDGE];

            void make_set(int x)
            {
                p[x]
            =x;
                rank[x]
            =0;
            }


            int find_set(int x)

                
            if(p[x]!=x)
                    p[x]
            =find_set(p[x]);
                
            return p[x];
            }


            void Union(int x,int y)
            {
                x
            =find_set(x);
                y
            =find_set(y);
                
            if(rank[x]>rank[y])
                    p[y]
            =x;
                
            else if(rank[x]<rank[y])
                    p[x]
            =y;
                
            else if(rank[x]==rank[y])
                
            {
                    p[x]
            =y;
                    rank[y]
            ++;
                }

            }


            bool cmp(int i,int j)//用于sort函數
            {
                
            return weight[i]<weight[j];
            }

            void Kruskal()
            {
                
            int i,min,index=0,count=0,k=0;
                
                max_weight
            =0;
                    
            for(i=1;i<=VNum;i++)
                      make_set(i);
                
                    sort(id,id
            +ENum,cmp);//對所有邊進行排序,注意id數組的妙用
                while(true){
                  min
            =id[index++];
                  
            if(find_set(start[min])!=find_set(end[min]))//對每條邊進行處理,如果起點和終點不在同一集合合并之
                    Union(start[min],end[min]);
                    result_s[k]
            =start[min];//保存結果
                            result_e[k++]=end[min];
                            count
            ++;
                    
            if(max_weight<weight[min])
                            max_weight
            =weight[min];
                   }

                  
                    
            if(count==VNum-1break;//當邊數等于節點數-1的時候表示已經完成
                }

            }






            int main()
            {
                
            int i;
                cin
            >>VNum>>ENum;
                
            for(i=0;i<ENum;i++){
                    cin
            >>start[i]>>end[i]>>weight[i];
                    id[i]
            =i;
                }

                    Kruskal();
                    cout
            <<max_weight<<endl<<VNum-1<<endl;
                    
            for(i=0;i<VNum-1;i++)
                   cout
            <<result_s[i]<<" "<<result_e[i]<<endl;
               
                    
            return 0;
            }


            posted on 2009-09-13 21:18 原語餓狼 閱讀(704) 評論(0)  編輯 收藏 引用 所屬分類: 圖論

            午夜人妻久久久久久久久| 97久久婷婷五月综合色d啪蜜芽| 久久亚洲日韩精品一区二区三区| 99精品国产综合久久久久五月天| 久久精品国产第一区二区三区 | 久久久人妻精品无码一区| 久久久久99精品成人片三人毛片 | 欧美色综合久久久久久| 久久久一本精品99久久精品88| 国产亚洲综合久久系列| 久久亚洲色一区二区三区| 亚洲精品高清国产一线久久| 久久婷婷综合中文字幕| 性做久久久久久久| 久久久无码精品午夜| 99久久精品费精品国产一区二区 | 午夜精品久久久久久99热| 国产精品xxxx国产喷水亚洲国产精品无码久久一区 | 久久综合九色综合久99| 亚洲精品乱码久久久久久蜜桃图片| 99久久免费国产精精品| 精品久久亚洲中文无码| 精品水蜜桃久久久久久久| 久久精品中文騷妇女内射| 国产成年无码久久久免费| 要久久爱在线免费观看| 久久影视综合亚洲| 国内精品久久久久久久coent| 久久精品国产亚洲AV高清热| 久久久久久久97| 久久精品国产日本波多野结衣| 久久久久人妻一区精品 | 99久久精品免费看国产一区二区三区 | 久久精品国产精品亜洲毛片| 好久久免费视频高清| 久久成人精品视频| 99久久中文字幕| 99久久精品免费看国产一区二区三区 | 久久久噜噜噜久久| 亚洲人AV永久一区二区三区久久 | 一本久久免费视频|