prim 算法(prim algorithm)

#include <iostream>
#include <math.h>
#include <list>

using namespace std;

void prim(int n, int u0, double **c)
{
    bool s[n];
    int closest[n];
    double lowcost[n];
    for(int i=0; i<n ;i++)
    {
        lowcost[i] = c[u0][i];
        closest[i] = u0;
        s[i] = false;
    }
    s[u0] = true;   //u0 is the origin, so the closet[u0] = -1, show that no point can reach it
    closest[u0] = -1;

    for(int i=0; i<n; i++)   //this can be n-1 times, because there are all n points, we choose the origin u0, leave n-1 points, get one point one times, so we need n-1 times cycle;
    {
        double temp = 0x7fffffff;
        int t = u0;
        for(int j=0; j<n; j++)
        {
            if(!s[j]&&lowcost[j]<temp)
            {
                temp = lowcost[j];
                t = j;
            }
        }
        if(t==u0)
            break;    //this means we have got the minimum spanning tree or the graph is not connected
        s[t] = true;
        for(int j=0; j<n ;j++)
        {
            if(!s[j]&&lowcost[j]>c[t][j])
            {
                lowcost[j] = c[t][j];
                closest[j] = t;
            }
        }

    }
    for(int i=0; i<n; i++)
    {
        if(s[i]==false)
        {
            cout << "the graph is not connected!!!";
            return;
        }
    }
   list<int> stack1;
   stack1.push_back(-1);

   while(stack1.size()!=0)  //output the result, the format is : firstcity secondcity, this shows there are relation between the two cities,if it is -s before one city, this city is the start city
   {
       int k = stack1.front();
       stack1.pop_front();
       for(int i=0; i<n; i++)
       {
           if(closest[i]==k)
           {
             cout << k << " " << i << endl;
             stack1.push_back(i);
           }

       }
   }

}

int main()
{
    int n;
    cout << "please input the number of cities and the number of relations\n" ;
    cin >> n;
    double **map = new double*[n];
    for(int i=0; i<n; i++)
    {
        map[i] = new double[n];
    }

    for(int i=0; i<n; i++)
        for(int j=0; j<n; j++)
    {
        map[i][j] = 0x7fffffff;
    }

    int m, temp1, temp2;
    double temp3;

    cin >> m;
    for(int k=0; k<m; k++)
    {
        cin >> temp1 >> temp2 >> temp3;   //the input file I writed it previous is wrong, just need to modyfy the index of city, the right index is equal to wrong index - 1
        map[temp1-1][temp2-1] = map[temp2-1][temp1-1] = temp3;
    }

    prim(n, 1, map);

    return 0;

}

/*data used to testthe number of city is wrong, so i minus 1 from them in program
6 10
1 2 6
1 3 1
1 4 5
2 3 5
2 5 3
3 5 6
3 6 4
4 6 2
3 4 5
5 6 6
*/
时间: 2024-10-02 21:33:54

prim 算法(prim algorithm)的相关文章

数据结构:最小生成树--Prim算法

最小生成树:Prim算法 最小生成树 给定一无向带权图,顶点数是n,要使图连通只需n-1条边,若这n-1条边的权值和最小,则称有这n个顶点和n-1条边构成了图的最小生成树(minimum-cost spanning tree). Prim算法 Prim算法是解决最小生成树的常用算法.它采取贪心策略,从指定的顶点开始寻找最小权值的邻接点.图G=<V,E>,初始时S={V0},把与V0相邻接,且边的权值最小的顶点加入到S.不断地把S中的顶点与V-S中顶点的最小权值边加入,直到所有顶点都已加入到S中

最小生成树--Prim算法,基于优先队列的Prim算法,Kruskal算法,Boruvka算法,“等价类”UnionFind

最小支撑树树--Prim算法,基于优先队列的Prim算法,Kruskal算法,Boruvka算法,“等价类”UnionFind 最小支撑树树 前几节中介绍的算法都是针对无权图的,本节将介绍带权图的最小支撑树(minimum spanning tree)算法.给定一个无向图G,并且它的每条边均权值,则MST是一个包括G的所有顶点及边的子集的图,这个子集保证图是连通的,并且子集中所有边的权值之和为所有子集中最小的. 本节中介绍三种算法求解图的最小生成树:Prim算法.Kruskal算法和Boruvk

贪婪技术与Prim算法

时间:2014.06.06 地点:基地 --------------------------------------------------------------------------- 一.简述贪婪技术 贪婪技术在贪婪过程中所做的每一步选择都满足如三个条件: 1.可行性:满足问题的约束 2局部优先:当前步骤中所有可行选择中最佳的局部选择 3不可取消:即选择一旦做出,在算法的后面步骤中无法改变 找零问题就是一个典型的贪婪技术应用:存在面额d1=25   d2=10  d3=5  d4=1的四

图的最小生成树——Prim算法

Prim算法 Prim算法求最小生成树是采取蓝白点的思想,白点代表已经加入最小生成树的点,蓝点表示未加入最小生成树的点. 进行n次循环,每次循环把一个蓝点变为白点,该蓝点应该是与白点相连的最小边权的是当前蓝点中最小的.这样就相当于向生成树中添加了n-1次最小的边,最后得到的一定是最小生成树. 1 #include<cstdio> 2 #include<cstring> 3 #define N 42000 4 using namespace std; 5 int next[N],to

Algorithm --&gt; Kruskal算法和Prim算法

最小生成树之Kruskal算法和Prim算法 根据图的深度优先遍历和广度优先遍历,可以用最少的边连接所有的顶点,而且不会形成回路.这种连接所有顶点并且路径唯一的树型结构称为生成树或扩展树.实际中,希望产生的生成树的所有边的权值和最小,称之为最小生成树.常见的最小生成树算法有Kruskal算法和Prim算法. Kruskal算法 每次选取权值最小的边.然后检查是否加入后形成回路,如果形成回路则需要放弃.最终构成最小生成树.n个顶点的图最小生成树步骤如下: 边的权值升序排序: 选取所有未遍历的边中权

最小生成树问题(prim算法)POJ-1258 Agri-Net

/* 这个题很水,但是,莫名其妙runtime error一晚上,重写了一遍就又没了,很伤心! 题意很简单,大致为n个村庄,连光缆,要求连上所有村庄的长度最短. 输入n,接着是n*n的矩阵,直接用prim算法写就行: */ #include<iostream> #include<cstdlib> #include<cstdio> #include<cstring> #include<algorithm> #include<cmath>

最小生成树(prim算法,Kruskal算法)c++实现

1.生成树的概念 连通图G的一个子图如果是一棵包含G的所有顶点的树,则该子图称为G的生成树. 生成树是连通图的极小连通子图.所谓极小是指:若在树中任意增加一条边,则将出现一个回路:若去掉一条边,将会使之变成非连通图. 生成树各边的权值总和称为生成树的权.权最小的生成树称为最小生成树. 2.最小生成树的性质用哲学的观点来说,每个事物都有自己特有的性质,那么图的最小生成树也是不例外的.按照生成树的定义,n 个顶点的连通网络的生成树有 n 个顶点.n-1 条边. 3.构造最小生成树,要解决以下两个问题

HDU 5253 Prim算法

http://acm.hdu.edu.cn/showproblem.php?pid=5253 Prim算法是 1.每次选出 (已经选出的)点集 能够连接 边权值最小的点 2.使用新找出的点能带来的新的更小的边权,来更新旧的较大的边权 3.重复,直到连接所有点 的贪心算法 使用优先权队列优化 查找 边权值最小的点 的步骤. #include <stdio.h> #include <string.h> #include <stdlib.h> #include <ios

[迷宫中的算法实践]迷宫生成算法&mdash;&mdash;Prim算法

       普里姆算法(Prim算法),图论中的一种算法,可在加权连通图里搜索最小生成树.意即由此算法搜索到的边子集所构成的树中,不但包括了连通图里的所有顶点(英语:Vertex (graph theory)),且其所有边的权值之和亦为最小.该算法于1930年由捷克数学家沃伊捷赫·亚尔尼克(英语:Vojtěch Jarník)发现:并在1957年由美国计算机科学家罗伯特·普里姆(英语:Robert C. Prim)独立发现:1959年,艾兹格·迪科斯彻再次发现了该算法.因此,在某些场合,普里姆

hdu 3371 最小生成树prim算法

Connect the Cities Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 8992    Accepted Submission(s): 2519 Problem Description In 2100, since the sea level rise, most of the cities disappear. Thoug