码迷,mamicode.com
首页 > 编程语言 > 详细

Prim算法

时间:2017-04-16 10:56:03      阅读:172      评论:0      收藏:0      [点我收藏+]

标签:clu   void   font   opera   const   min   queue   []   入队   

 

#include<iostream>
using  namespace std;

#define MAX 100
#define MAXCOST 0x7fffffff

int map[MAX][MAX];
//二维数组适合复杂树
int prim(int map[][MAX], int n)
{
    int dis[MAX];
    int i, j, min, minid, sum = 0;
    for (i = 2; i <= n; i++)
    {
        dis[i] = map[1][i];//dis[i]表示从根节点到i结点的最小距离
    }
    for (i = 2; i <= n; i++)
    {
        min = MAXCOST;
        minid = 0;
        for (j = 2; j <= n; j++)
        {
            if (dis[j] < min && dis[j] != 0)
            {
                min = dis[j];
                minid = j;
            }
        }
        sum += min;
        dis[minid] = 0;
        for (j = 2; j <= n; j++)
        {
            if (map[minid][j] < dis[j])
            {
                dis[j] = map[minid][j];
            }
        }
    }
    return sum;
}

int main()
{
    int i, j, k, m, n;
    int cost;
    cin >> n >> m;//n顶点的个数,m边的个数
    //初始化图G
    for (i = 1; i <= n; i++)
    {
        for (j = 1; j <= n; j++)
        {
            map[i][j] = MAXCOST;
        }
    }
    //构建图G
    for (k = 1; k <= m; k++)
    {
        cin >> i >> j >> cost;
        map[i][j] = cost;
        map[j][i] = cost;
    }
    //求解最小生成树
    cost = prim(map, n);
    //输出最小权值和
    cout << "最小权值和=" << cost << endl;
    return 0;
}
优先队列表示Prim算法
struct node {  
    int v, len;  
    node(int v = 0, int len = 0) :v(v), len(len) {}  
    bool operator < (const node &a)const {  // 加入队列的元素自动按距离从小到大排序  
        return len> a.len;  
    }  
};

vector<node> G[maxn];
int vis[maxn];
int dis[maxn];

void init() {  
    for (int i = 0; i<maxn; i++) {  
        G[i].clear();  
        dis[i] = INF;  
        vis[i] = false;  
    }  
}  
int Prim(int s) {  
    priority_queue<node>Q; // 定义优先队列  
    int ans = 0;  
    Q.push(node(s,0));  // 起点加入队列  
    while (!Q.empty()) {   
        node now = Q.top(); Q.pop();  // 取出距离最小的点  
        int v = now.v;  
        if (vis[v]) continue;  // 同一个节点,可能会推入2次或2次以上队列,这样第一个被标记后,剩下的需要直接跳过。  
        vis[v] = true;  // 标记一下  
        ans += now.len;  
        for (int i = 0; i<G[v].size(); i++) {  // 开始更新  
            int v2 = G[v][i].v;  
            int len = G[v][i].len;  
            if (!vis[v2] && dis[v2] > len) {   
                dis[v2] = len;  
                Q.push(node(v2, dis[v2]));  // 更新的点加入队列并排序  
            }  
        }  
    }  
    return ans; 
}  

Prim算法

标签:clu   void   font   opera   const   min   queue   []   入队   

原文地址:http://www.cnblogs.com/--lr/p/6718103.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!