zoukankan      html  css  js  c++  java
  • 最小生成树(kruskal)

    Kruskal算法是一种用来寻找最小生成树的算法,由Joseph Kruskal在1956年发表。用来解决同样问题的还有Prim算法和Boruvka算法等。三种算法都是贪婪算法的应用。和Boruvka算法不同的地方是,Kruskal算法在图中存在相同权值的边时也有效。

    时间复杂度:elog2e  e为图中的边数

    原理可以参考这篇文章:

    http://www.cnblogs.com/biyeymyhjob/archive/2012/07/30/2615542.html

    实现如下:

     1 #include <iostream>
     2 #include <vector>
     3 #include <queue>
     4 #include <algorithm>
     5 using namespace std;
     6 
     7 vector<pair<int,int> > eg[100];
     8 
     9 typedef pair<int,int> pa;
    10 
    11 struct node
    12 {
    13           int x,y,w;
    14 
    15           node(int a,int b,int c)
    16           { x=a;y=b;w=c;}
    17 
    18           bool operator <(const node &a)const
    19           { return w<a.w;}
    20           //为了实现sort,<是升序(小的在前),>是降序
    21 };
    22 
    23 void kruskal(int n,int d)
    24 {
    25           int vset[100];
    26           //辅助数组,判定两个顶点是否连通
    27 
    28           vector<node> E;
    29           //保存所有边
    30           
    31           int k,j;
    32           
    33           //init
    34           for(int i = 0;i<n;i++)
    35           {
    36                     vset[i] = i;
    37                     for(int j = 0;j<eg[i].size();j++)
    38                     {
    39                               pa x = eg[i][j];
    40                               E.push_back(node(i,x.first,x.second));
    41                     }
    42           }
    43           sort(E.begin(),E.end());
    44 
    45           k = 1;
    46           //生成的边数,最后要刚好为总边数
    47           int m = 0,sn1,sn2;
    48           //E中的下标
    49           
    50           while(k<n)
    51           {
    52                     //sn1和sn2为两个集合
    53                     sn1 = vset[E[m].x];
    54                     sn2 = vset[E[m].y];
    55                     if(sn1!=sn2)
    56                     {
    57                               cout<<E[m].x<<"->"<<E[m].y<<" : "<<E[m].w<<endl;
    58                               //集合的表示
    59                               for(int i = 0;i<n;i++)
    60                                         if(vset[i] == sn2)
    61                                                   vset[i] = sn1;
    62                               k++;
    63                     }
    64                     m++;
    65           }
    66 
    67 }
    68 
    69 
    70 int main()
    71 {
    72           int n,d;
    73           cin>>n>>d;
    74           for(int i = 0;i<d;i++)
    75           {
    76                     int t,s,w;
    77                     cin>>t>>s>>w;
    78                     eg[t].push_back(make_pair(s,w));
    79                     eg[s].push_back(make_pair(t,w));
    80           }
    81           kruskal(n,d);
    82 
    83 
    84 
    85 }
    86 /*
    87 6 8
    88 0 1 2
    89 0 3 4
    90 1 4 4
    91 2 0 5
    92 2 5 2
    93 3 4 3
    94 3 5 7
    95 5 4 3
    96 */
  • 相关阅读:
    sql server 存储过程中使用变量表,临时表的分析
    C#实现图(Graph)
    C#实现平衡多路查找树(B树)
    设置webstorm缩写代码
    img标签在div中水平垂直居中--两种实现方式
    setInterval()的时间参数无法随参数的变化而变化
    seajs的模块化开发--实践笔记
    Xcode执行Analyze静态分析
    iOS10 下APP内跳转到系统设置WIFI界面
    convertRect view之间坐标系的转换
  • 原文地址:https://www.cnblogs.com/qlky/p/4997535.html
Copyright © 2011-2022 走看看