数据结构 _ 基础练习 _ 7-10 公路村村通
作者:互联网
原题
点此链接1
题目分析
可参考课本(高等教育出版社 - 陈越 - 《数据结构》)P225中关于prim算法的描述解题。
本题相对于课本描述的算法来说,不需要考虑 父节点 (parent),只需要考虑一个总的WPL就行。
代码
/**
* @file Road Connect Every Village.cpp
* @author your name (you@domain.com)
* @brief 公路村村通 : https://pintia.cn/problem-sets/15/problems/718
* @version 0.1
* @date 2021-02-06
*
* @copyright Copyright (c) 2021
*
*/
#include <algorithm>
#include <iostream>
#include <map>
#include <vector>
#include <queue>
#include <cmath>
using namespace std;
const int intMax = pow(2, 15) - 1;
/*
* 解题思路:
* prim 算法描述
* 基本变量
* 1. 路径点集合:
* 点 - 特殊值(初始为最大值),采用带索引的向量集
* 点表示当前索引
* 特殊值:
* 无穷 表示从未访问过的点;
* 0 表示树内点;
* >0 表示当前点距离树的距离
* 2. 最终费用:只需要计算一个费用和就行!
* (3.父节点)
*
* 初始化
* v0 特殊值应为 0
* 对v0的每一个邻接点,需要初始化路径点集合中的特殊值为 到v0 的 路经长
* (更新父节点为v0)
*
* while(路径集合中找不到符合要求的路径了)
* {
* 选择 路径集合 中 具有 最小路径的 点 A
* 确定A点收入 收集点集 中
* 对点A的每一个邻接点
* 选择树外点B
* 如果 点A到B的距离 小于 点B到树的距离
* 更新 B到树的距离
* (更新B的父结点)
* }
* 判断是否找到了每一个点以输出
*/
int main()
{
int v, e;
cin >> v >> e;
vector<vector<pair<int, int>>> data(v);
for (auto i = 0; i < e; i++)
{
int p1, p2, cost;
cin >> p1 >> p2 >> cost;
// @warning 减去1 保证0号是有效的
// 这道题不需要考虑城镇号,所以其他地方不需要再作进一步考虑了
data[p1 - 1].push_back({p2 - 1, cost});
data[p2 - 1].push_back({p1 - 1, cost});
}
vector<int> dis(v, intMax); // 路经长
auto MinIndex = [&dis, v]() -> int {
auto index = -1;
auto min = intMax;
for (auto i = 0; i < v; i++)
if (dis[i] < min && dis[i])
{
index = i;
min = dis[i];
}
return index;
};
// 从 0 开始
auto sum = 0;
dis[0] = 0;
for (auto &r : data[0])
dis[r.first] = r.second;
while (true)
{
// 选择距树最短的那个点
auto minIndex = MinIndex();
if (minIndex == -1)
break;
sum += dis[minIndex];
dis[minIndex] = 0;
// 对每一个邻接点
for (auto &r : data[minIndex])
// 对每一个树外点
if (dis[r.first] && dis[r.first] > r.second)
dis[r.first] = r.second;
}
if (count_if(dis.begin(), dis.end(), [](int in) { return !in; }) != v)
cout << -1 << endl;
else
cout << sum << endl;
return 0;
}
标签:minIndex,10,include,int,auto,村村通,数据结构,data,dis 来源: https://blog.csdn.net/u013639740/article/details/113728505