算法设计和分析(Prim算法构建最小生成树)

问题:

给定无向图G(N,M)表明图G有N个顶点,M条边,通过Prim算法构造一个最小生成树

分析:

算法流程:

构造好的最小生成树就是step6

运行代码:

#include<cstdio>
#include<string.h>
#include<algorithm>
#include<cmath>
#include<iostream>
#include<vector>
#include<queue>
#include<set>
#include<map>
#include<cctype>
#include<stack>
#define ios ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
#define mem(a,x) memset(a,x,sizeof(a))
#define lson rt<<1,l,mid
#define rson rt<<1|1,mid + 1,r
#define P pair<int,int>
#define ull unsigned long long
using namespace std;
typedef long long ll;
const int maxn = 100;
const ll mod = 998244353;
const int inf = 0x3f3f3f3f;
const long long INF = 0x3f3f3f3f3f3f3f3f;
const double eps = 1e-7;

int n, m;                                // 假设有n个点,m条边
int edge[maxn][maxn];                    // 用邻接矩阵来存图
int vis[maxn];                            // 记录某点是否加入最小生成树中
int dist[maxn];                            // 记录最小生成树中每一个点邻接的最短边
int father[maxn];                        // 记录某点的父亲节点,记录构成最小生成树的边
int main()
{

    scanf("%d %d", &n, &m);
    memset(edge, inf, sizeof edge);        // 将临界矩阵初始化为inf ,edge[u][v] == inf 代表u和v不连通
    for (int i = 1; i <= n; ++i)        // 将数据进行初始化
    {
        vis[i] = false;
        father[i] = -1;
        dist[i] = inf;
        edge[i][i] = 0;
    }
    for (int i = 1; i <= m; ++i)
    {
        int u, v,val;
        scanf("%d %d %d", &u, &v,&val);                // 获取边的起点、终点和权值
        edge[u][v] = min(val , edge[u][v]);
        edge[v][u] = min(val , edge[v][u]);            // 用邻接矩阵存图 , 对于起点和终点相同的边仅保留最小值即可
    }
    vis[1] = true;                                    // 将1号点添加进最小生成树中,作为树根
    for (int i = 1; i <= n; ++i)
    {
        dist[i] = edge[1][i];
        father[i] = 1;
    }
    father[1] = -1;                                    // 将树根的父亲节点设为-1
    for (int i = 1; i <= n; ++i)
    {
        int v = -1;
        int tmp = inf;
        for (int j = 1; j <= n; ++j)                // 在最小生成树之外寻找最短路径
        {
            if (!vis[j] && dist[j] < tmp)
            {
                v = j;
                tmp = dist[j];
            }
        }
        vis[v] = true;                                // 将寻找到的最短路径的终点加入最小生成树中
        for (int j = 1; j <= n; ++j)
        {
            if (!vis[j] && edge[v][j] < dist[j])    // 在有新的点加入最小生成树之后,要更新dist中的值
            {
                dist[j] = edge[v][j];
                father[j] = v;
            }
        }
    }
    int sum = 0;
    for (int i = 1; i <= n; ++i) sum += dist[i];    //输出最小生成树的权值和,以及构成最小生成树的边
    printf("最小生成树的权值是:%d\n", sum);
    printf("构成最小生成树的边为:\n");
    for (int i = 1; i <= n; ++i)
    {
        if (father[i] != -1)
        {
            printf("%d %d\n", father[i], i);
        }
    }
    return 0;
}

/*
6 9
1 5 1
1 6 2
1 2 3
2 6 4
2 3 5
3 6 6
3 4 7
4 6 8
4 5 9

样例

*/

Prim

原文地址:https://www.cnblogs.com/DreamACMer/p/12375400.html

时间: 2024-08-03 02:02:43

算法设计和分析(Prim算法构建最小生成树)的相关文章

【算法设计与分析】9、最小生成树,贪心算法实现

/** * 书本:<算法分析与设计> * 功能:实现用Prim算法实现寻找最小生成树 * 文件:PrimMixTree.cpp * 时间:2015年1月4日19:42:57 * 作者:cutter_point */ #include <iostream> #include <fstream> //文件输入输出流 using namespace std; const int N = 6; //这个图是一个6*6的矩阵 const int inf = 9999; ifstr

《算法设计与分析》--算法第二章上机实践报告

开门见山,直接上题目. 7-2 改写二分搜索算法 (20 分) 设a[0:n-1]是已排好序的数组,请改写二分搜索算法,使得当x不在数组中时,返回小于x的最大元素位置i和大于x的最小元素位置j.当搜索元素在数组中时,i和j相同,均为x在数组中的位置. 输入格式: 输入有两行: 第一行是n值和x值: 第二行是n个不相同的整数组成的非降序序列,每个整数之间以空格分隔. 输出格式: 输出小于x的最大元素的最大下标i和大于x的最小元素的最小下标j.当搜索元素在数组中时,i和j相同. 提示:若x小于全部数

《算法设计与分析》--算法第二章分治感想

分治法体会 分治法所能解决的问题一般具有以下几个特征: 1) 该问题的规模缩小到一定的程度就可以容易地解决 2) 该问题可以分解为若干个规模较小的相同问题,即该问题具有最优子结构性质. 3) 利用该问题分解出的子问题的解可以合并为该问题的解: 4) 该问题所分解出的各个子问题是相互独立的,即子问题之间不包含公共的子问题. 这个方法太棒了,我以前从来想不到用这个思想. 等我参悟了这个方法肯定会变强! 结对编程 结对编程太妙了,抱大佬的大腿,对自己的思想也有很大启发,太棒了. 原文地址:https:

(转)常用的算法设计与分析-一夜星辰的博客

算法设计与分析 分治法 思想 1. 将一个规模为n的问题分解为k个规模较小的子问题,这些子问题互相独立且与原问题相同.递归地解这些子问题,然后将各子问题的解合并得到原问题的解. 2. divide-and-conquer(P) { if(|P| <= n0)adhoc(P); divide P into samller subinstances P1,P2...,Pk; for(int i = 1;i < k;i++) { yi = divide-and-conquer(Pi); } retu

算法设计与分析基础(第3版)读书笔记(及几处翻译上的错误~~)

算法设计与分析基础(第3版) p16 in-place翻译为'在位'?'就地'更合适点 p38 amortized应翻译为'均摊','摊销'这个词简直莫名其妙(可能因为翻译是做算法交易导致的?) p64 迭代优于递归(迭代始终是增量式的,而递归就没办法增量了,除非能够dump整个运行时栈) p73 通过算法可视化得到一个更好的非递归算法(人的图像认知直觉思维?) p79 验证一个拓扑是环.星.还是团?(这个地方有点意思,因为我想到了动态的Verify) p87 凸包问题:从数据结构上讲,Set<

算法设计与分析(屈婉玲)pdf

下载地址:网盘下载 算法设计与分析本教材为计算机科学技术专业核心课程"算法设计与分析"教材.<算法设计与分析>以算法设计技术和分析方法为主线来组织各知识单元,主要内容包括基础知识.分治策略.动态规划.贪心法.回溯与分支限界.算法分析与问题的计算复杂度.NP完全性.近似算法.随机算法.处理难解问题的策略等.书中突出对问题本身的分析和求解方法的阐述,从问题建模.算法设计与分析.改进措施等方面给出适当的建议,同时也简要介绍了计算复杂性理论的核心内容和处理难解问题的一些新技术. &

算法设计与分析 ------最近对问题与8枚硬币问题

利用减治法实现8枚硬币问题: 参考资料:http://blog.csdn.net/wwj_748/article/details/8863503    算法设计--八枚硬币问题 1 #include "stdafx.h" 2 #include <iostream> 3 #include <stdio.h> 4 using namespace std; 5 6 7 void eightcoin(int arr[]); 8 void compare(int a,in

《计算机算法设计与分析》v4 第1章 算法概述 算法实现题答案

博主今年刚上大三,正好开算法这门课.由于博主本人比较喜欢算法但又比较懒,啃不动算法导论,所以决定拿这本书下手. 这本书是王晓东的第四版<计算机算法设计与分析>.初步打算将每章后面的算法题都用代码实现. 有些题跟某个ACM题目很像,我会把该ACM题的链接贴上.有的题没OJ交所以可能是错的.如有发现,还望指出. 1-1 统计数字问题 http://poj.org/problem?id=2282 这个题要按位分解,一位一位的来处理. #include<iostream> #include

【通知】《算法设计与分析》实验课、理论课补课、考试时间、加分等安排 及 个人目标设定

Logistic回归为概率型非线性回归模型,是研究二分类观察结果与一些影响因素之间关系的一种多 变量分析方法.通常的问题是,研究某些因素条件下某个结果是否发生,比如医学中根据病人的一些症状来判断它是 否患有某种病. 在讲解Logistic回归理论之前,我们先从LR分类器说起.LR分类器,即Logistic Regression Classifier. 在分类情形下,经过学习后的LR分类器是一组权值,当测试样本的数据输入时,这组权值与测试数据按 照线性加和得到 这里是每个样本的个特征. 之后按照s

算法设计与分析——回溯法算法模板

以深度优先方式系统搜索问题解的算法称为回溯法.在回溯法中,解空间树主要分为了四种子集树.排列树.n叉树和不确定树. 在<算法设计与分析课本>中介绍了11个回溯法的问题样例,这里根据解空间树的类型做一个分类. 子集树 装载问题 符号三角形问题 0-1背包问题 最大团问题 算法模板: void backtrack(int t) { if(搜索到叶子结点) { return; } for(i=0; i<=1; i++) //01二叉树 { if(满足约束函数和限界函数)//剪枝 { backt