zoukankan      html  css  js  c++  java
  • 最小生成树之Prim

    A:生成树

    B:未被访问过的点的集合

    pre[i]:生成树中i的前驱节点。

    A中的dis[i]:生成树中包含点i的边的长度。

    B中的dis[i]: i到A的最短距离

    vis[]:标记是否遍历过(是否属于A)

    Prim算法的思想

    1.任选一点,不妨选择第一个点,加入生成树A。

    2.遍历B,寻找一点u,使其到A的距离最小(就是A中也找了一点v)。添加u到A中(vis)。记录这条边及其权值(pre,dis)。

    3.更新与u相连的点的dis和pre

    4.循环直到遍历所有可达的点。

    View Code
    #include <iostream>
    #include <climits> 
    using namespace std;
    
    #define Max 100
    void Prim(int n, int map[Max][Max], int dis[Max], int pre[Max])
    {
        bool visit[Max];
        
        //初始化 
        for (int i = 2; i <= n; ++i)
        {
            visit[i] = false;
            
            dis[i] = map[1][i];
            
            pre[i] = 1;
        }
        
        visit[1] = true;
        
        dis[1] = 0;
        
        //循环n-1次,每次加入一个点 
        for (int i = 1; i < n; ++i)
        {
            int min = INT_MAX;
            
            int next = 0;
            
            //找到最小边 
            for (int j = 2; j <= n; ++j) 
            {
                if (!visit[j] && dis[j] < min)
                {
                    min = dis[j];
                    
                    next = j;
                }
            }
            
            //找不到 
            if (next == 0)return;
            
            //加入生成树
            visit[next] = true;
            
            //更新与k相邻的顶点。
            for (int j = 2; j <= n; j++)
            {
                if (!visit[j] && map[j][next] < INT_MAX && dis[j] > map[j][next])
                {
                    dis[j] = map[j][next];
                    
                    pre[j] = next;
                }
            }
        }
    }

    基本的最小生成树题目。

    View Code
    /*
    【题目来源】 
    http://soj.me/1090
    最小生成树。
    【题目分析】
    给定邻接矩阵,求最小生成树的最长边。
    【思路分析】
    prim算法。 
    */
    #include <iostream>
    #include <algorithm>
    #include <iterator>
    #include <cstring>
    #include <climits>
    using namespace std;
    
    #define Max 502
    
    int map[Max][Max], dis[Max], pre[Max];
    
    bool Prim(int n)
    {
        bool vis[Max];
        
        //初始化 
        for (int i = 2; i <= n; ++i)
        {
            dis[i] = map[1][i];
            
            vis[i] = false;
            
            pre[i] = 1;
        }
        
        vis[1] = true;
        
        dis[1] = 0;
        
        //循环n-1次 
        for (int i = 1; i < n; ++i)
        {
            int min = INT_MAX;
            
            int k = 0;
            
            //找到最小边 
            for (int j = 2; j <= n; ++j)
            {
                if (min > dis[j] && !vis[j])
                {
                    min = dis[j];
                    
                    k = j;
                }
            }
            
            //找不到 
            if (k == 0)    return false;
            
            //加入生成树 
            vis[k] = true;
            
            //更新其他各点 
            for (int j = 1; j <= n; ++j)
            {
                if (!vis[j] && map[k][j] < dis[j] && map[j][k] != INT_MAX)
                {
                    dis[j] = map[k][j];
                    
                    pre[j] = k;
                }
            }
        }
    }
    
    
    int main()
    {
        int n;
        
        int m;
        
        cin >> m;
        
        int m2 = m;
        
        while (m--)
        {
            if  (m != m2-1) cout << endl;
            
            cin >> n;
            
            memset(dis, 0, sizeof(dis));
            
            for (int i = 1; i <= n; ++i)
            {
                for (int j = 1; j <= n; ++j)
                {
                    cin >> map[i][j];
                }
            }
            
            Prim(n);
            
            cout << *max_element(dis, dis+n+1) << endl;
        }
        
    }
  • 相关阅读:
    最近在项目中使用ibatis小结
    35 岁前程序员要规划好的四件事
    C# webbrowser小结
    高并发网站架构
    高斯混合模型(GMM)
    EM算法学习(Expectation Maximization Algorithm)
    如何用CSS3美化菜单
    Intellij IDEA配置自动同步到FTP服务器
    Mac 快速休眠关机重启锁屏
    JavaScript并行运算新机遇——Web Workers的神奇魔法
  • 原文地址:https://www.cnblogs.com/chenyg32/p/2908133.html
Copyright © 2011-2022 走看看