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

    Prim算法 

      构造过程:

        1)任选一个点,以这个点开始,寻找该点可以访问的所有的边;

        2)在可以访问的所有边中找到最小边,这个边必须有一个点还没有访问过(防止出现回路),将还没有访问的点加入集合,并记录添加的边;(加点法)

        3)寻找当前集合可以访问的所有边,重复2过程,直到没有新的点可以加入,即成功构造出最小生成树。

    Kruskal算法

      构造过程:

        1)初始状态是所有点独立的一个图,并没有边相连;

        2)在边集中选择权值最小的最短边,如果这条边依附的顶点在图中的不同连通分量上(不形成回路),就将这条边加进去,否则舍去这条边继续选择下一条最短边;

        3)重复2过程,直到构造出最小生成树。


    通过一道简单例题来看看具体代码如何实现:

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1233

     Prime写法:

     1 #include<iostream>
     2 #include<cstring>
     3 using namespace std;
     4 const int INF = 0x3f3f3f3f;
     5 int n, ans;
     6 int edge[110][110];
     7 int dis[110];    //顶点i到最小生成树顶点集合的最短距离
     8 int vis[110];
     9 void prime()
    10 {
    11     ans = 0;
    12     for(int i = 1; i <= n; i++)
    13         dis[i] = edge[1][i];
    14     dis[1] = 0;
    15     vis[1] = 1;
    16     for(int k = 2; k <= n; k++)
    17     {
    18         int minn = INF;    //需要加入的边权
    19         int pos;    //要加入的顶点序号
    20         for(int i = 1; i <= n; i++)
    21         {
    22             if(!vis[i] && dis[i] < minn)
    23             {
    24                 minn = dis[i];
    25                 pos = i;
    26             }
    27         }
    28         if(minn == INF)    //不是连通图
    29             break;
    30         vis[pos] = 1;
    31         ans += minn;
    32         for(int i = 1; i <= n; i++)
    33         {
    34             if(!vis[i] && dis[i] > edge[pos][i])
    35             {
    36                 dis[i] = edge[pos][i];
    37             }
    38         }
    39     }
    40 }
    41 
    42 int main()
    43 {
    44     int s, e, w;
    45     while(cin >> n && n)
    46     {
    47         memset(vis, 0, sizeof(vis));
    48         int m = n * (n - 1) / 2;
    49         for(int i = 1; i <= m; i++)
    50         {
    51             cin >> s >> e >> w;
    52             edge[s][e] = edge[e][s] = w;    //无向图
    53         }
    54         prime();
    55         cout << ans << endl;
    56     }
    57     return 0;
    58 }

    kruskal写法:

     1 #include<iostream>
     2 #include<algorithm>
     3 using namespace std;
     4 const int maxn = 1e4 + 10;
     5 int n, m, ans;
     6 int far[maxn];
     7 struct node
     8 {
     9     int s, e, w;
    10 } edge[maxn];
    11 bool cmp(node a, node b)
    12 {
    13     return a.w < b.w;
    14 }
    15 int find(int x)
    16 {
    17     return (far[x] == x) ? far[x] : (far[x] = find(far[x]));
    18 }
    19 void unite(int x, int y)
    20 {
    21     int xx = find(x);
    22     int yy = find(y);
    23     if(xx != yy)
    24         far[yy] = xx;
    25 }
    26 void kruskal()
    27 {
    28     ans = 0;
    29     sort(edge, edge + m, cmp);
    30     for(int i = 0; i <= n; i++)
    31         far[i] = i;
    32     for(int i = 0; i < m; i++)
    33     {
    34         int xx = find(edge[i].s);
    35         int yy = find(edge[i].e);
    36         if(xx != yy)
    37         {
    38             unite(edge[i].s, edge[i].e);
    39             ans += edge[i].w;
    40         }
    41     }
    42 }
    43 int main()
    44 {
    45     while(cin >> n && n)
    46     {
    47         m = n * (n - 1) / 2;
    48         for(int i = 0; i < m; i++)
    49         {
    50             cin >> edge[i].s >> edge[i].e >> edge[i].w;
    51         }
    52         kruskal();
    53         cout << ans << endl;
    54     }
    55     return 0;
    56 }
  • 相关阅读:
    规范的html页面
    什么是MVC (模型 视图 控制器)?
    MVC概念
    MVC实用集锦(1)
    三层架构与MVC的区别
    spring-data-jpa的简单介绍
    Spring和SpringMVC的区别
    Spring常用注解汇总
    jmeter---CSV文件设置操作
    Linux----软件包管理
  • 原文地址:https://www.cnblogs.com/friend-A/p/9209628.html
Copyright © 2011-2022 走看看