图结构练习——最小生成树

来源:互联网 发布:ui需要哪些软件 编辑:程序博客网 时间:2024/06/15 14:57

图结构练习——最小生成树

Time Limit: 1000MS Memory limit: 65536K

题目描述

 有n个城市,其中有些城市之间可以修建公路,修建不同的公路费用是不同的。现在我们想知道,最少花多少钱修公路可以将所有的城市连在一起,使在任意一城市出发,可以到达其他任意的城市。
 

输入

 输入包含多组数据,格式如下。
第一行包括两个整数n m,代表城市个数和可以修建的公路个数。(n <= 100, m <=10000)
剩下m行每行3个正整数a b c,代表城市a 和城市b之间可以修建一条公路,代价为c。
 

输出

 每组输出占一行,仅输出最小花费。

示例输入

3 21 2 11 3 11 0

示例输出

20

提示

 

来源

 赵利强

示例程序

 
#include <stdio.h>#include <iostream>#include <stdlib.h>#include <string.h>#include <queue>#define inf 999999using namespace std;int n, m;int map[110][110], visit[110], dis[110];//普里姆算法:首先将所有的边都放到待选区中,也就是dis[], 从顶点开始,遍历这一行也就是两个节点之间最小边,加入到最小生成树中,//           并把它从待选区中去掉,也就是visit[]赋值为1,遍历所有的节点,根据上一个节点找到的最小边的弧头,再从弧头所在的行开始遍历,直到遍历介结束void MiniSpanTree(int x){    int k, min, sum = 0;    visit[0] = 1;                                               //从顶点n开始遍历,遍历就标记为已遍历    for(int i = 1; i < x; i++)                                  //初始化辅助数组,使每一个辅助数组中存着当前行所有的数据        dis[i] = map[0][i];    for(int i = 1; i < x; i++)                                  //对所有的顶点都遍历    {        min = inf;                                              //初始化最小值,用来寻找这一行中最小的权值        for(int j = 0; j < x; j++)                              //遍历此行所有的数据,若数据没有遍历过并且小于最小值,赋值为最小值,并记录下当前的位置,        {            if(visit[j] == 0 && min > dis[j])            {                min = dis[j];                k = j;                                          //记录下当前位置,用来寻找下一次要遍历的行            }        }        sum = sum + min;                                        //sum的就是最小生成树的权值        visit[k] = 1;                                           //标记为已遍历,此列不在遍历        for(int j = 0; j < x; j++)                              //遍历k行所有的数据,把没有遍历过的并且小于当前值得赋值到辅助数组,也就是待选区中,就是        {                                                       //就是把当前节点和k节点的所有边的权值放到待选区中,但是只筛选小于当前权值的            if(visit[j] == 0 && dis[j] > map[k][j])                         dis[j] = map[k][j];        }    }    cout << sum << endl;}int main(){    while(cin >> n >> m)    {        memset(visit, 0, sizeof(visit));                        //初始化        memset(map, 0, sizeof(map));        for(int i = 0; i < n ; i++)                             //初始化邻接矩阵,因为为无向图,以对角线对称,对角线处必定为0,其他位置赋值为无限大        {            for(int j = 0; j < n; j++)            {                if(i == j)                    map[i][j] = 0;                else                    map[i][j] = inf;            }        }        for(int i = 0; i < m; i++)        {            int a, b, c;            cin >> a >> b >> c;            if(c < map[a - 1][b - 1])                           //因为数组坐标从0开始,而输出的数据的坐标却是从1开始,将其变化为数组中坐标                map[a - 1][b - 1] = map[b - 1][a - 1] = c;        }        MiniSpanTree(n);    }    return 0;}

0 0
原创粉丝点击