PTA 08-图7 公路村村通 (30分)
现有村落间道路的统计数据表中,列出了有可能建设成标准公路的若干条道路的成本,求使每个村落都有公路连通所需要的最低成本。
输入格式:
输入数据包括城镇数目正整数NN(\le 1000≤1000)和候选道路数目MM(\le 3N≤3N);随后的MM行对应MM条道路,每行给出3个正整数,分别是该条道路直接连通的两个城镇的编号以及该道路改建的预算成本。为简单起见,城镇从1到NN编号。
输出格式:
输出村村通需要的最低成本。如果输入数据不足以保证畅通,则输出-1−1,表示需要建设更多公路。
输入样例:
6 15
1 2 5
1 3 3
1 4 7
1 5 4
1 6 2
2 3 4
2 4 6
2 5 2
2 6 6
3 4 6
3 5 1
3 6 1
4 5 10
4 6 8
5 6 3
输出样例:
12
/*
* 这题边数e <= 3*顶点数 不是稀疏图 故以邻接矩阵进行存储 采用prim算法。 (下面也写了个kruskal加最小堆的实现)
* findMin()函数找最小值可以用最小堆进行优化。(这里不用最小堆优化用了24ms~~ 用最小堆和kruskal写12ms- -!)
*/
#include "iostream"
using namespace std;
#define INF 999999
int map[][];
int n, m;
int lowCost[];
long ans = ;
int findMin() {
int minCost = INF;
int k, j;
for (k = , j = ; j <= n; j++) {
if (lowCost[j] && lowCost[j] < minCost) {
minCost = lowCost[j];
k = j;
}
}
return k;
}
int prim() {
for (int i = ; i <= n; i++) {
lowCost[i] = map[][i];
}
lowCost[] = ; /* 从序号为1的顶点出发生成最小生成树 */
for (int i = ; i < n; i++) { /* 生成树还需要收n-1个节点 */
int k = findMin(); /* 找到到生成树距离最短的节点 */
if (k) {
ans += lowCost[k];
lowCost[k] = ;
for (int j = ; j <= n; j++) { /* 更新当前的最小生成树 */
if (lowCost[j] && map[k][j] < lowCost[j]) {
lowCost[j] = map[k][j];
}
}
}
else {
return -;
}
}
return ans;
}
void init() {
cin >> n >> m;
for (int i = ; i <= n; i++)
for (int j = ; j <= n; j++) {
if (i == j) {
map[i][j] = ;
}
else {
map[i][j] = INF;
}
}
while (m--) {
int c1, c2, c3;
cin >> c1 >> c2 >> c3;
map[c1][c2] = map[c2][c1] = c3;
}
}
int main() {
init();
cout<<prim()<<endl;
}
/*
* kruskal加最小堆的实现(可能是数据量比较小吧~ 这个稠密图用krukal加了个最小堆跑的比前面的prim快了一倍)
*/
#include "iostream"
using namespace std;
#define INF 0
struct Node {
int s, e;
int cost;
}edge[];
int father[];
int Size = ;
int v, e;
void makeHeap() { /* 将数组调整成小顶堆 O(e)的时间复杂度 */
int child, parent;
Size = e;
edge[].cost = INF; /* 哨兵 */
int i = Size / ;
for (; i >= ; i--) {
Node temp = edge[i];
for (parent = i; parent * <= Size; parent = child)
{
child = parent * ; /* 先指向左孩子 */
if ((child != Size) && edge[child].cost > edge[child + ].cost) { /* 右孩子*/
child++;
}
if (temp.cost <= edge[child].cost) {
break;
}
else
edge[parent] = edge[child];
}
edge[parent] = temp;
}
}
Node deleteMinFromHeap() { /* 从小顶堆中删除元素 在调整成小顶堆 时间复杂度O(log e)*/
Node temp = edge[Size--];
Node minItem = edge[];
//cout << Size << endl;
int parent, child;
for ( parent = ; parent * <= Size; parent = child) {
child = parent * ;
if ((child != Size) && (edge[child].cost > edge[child+].cost)) {
child += ; /* 找左右孩子中较小者 */
}
if (temp.cost <= edge[child].cost) break;
else edge[parent] = edge[child];
}
edge[parent] = temp;
return minItem;
}
void init() {
// cout << "v--->" << v << endl;
for (int i = ; i <= v; i++)
father[i] = -; /* 初始化为当前树的节点数的相反数 */
}
int find(int x) { /* 查询根节点 */
if (father[x] <= -)
return x;
else
return father[x] = find(father[x]); /* 路径压缩 */
} void Union(int x, int y) {
x = find(x);
y = find(y);
if (father[x] < father[y]) { /* 按节点数大小进行归并 */
father[x] += father[y];
father[y] = x;
}
else {
father[y] += father[x];
father[x] = y;
}
}
int main() {
int ans = ;
cin >> v >> e;
for (int i = ; i <= e; i++) {
cin >> edge[i].s >> edge[i].e >> edge[i].cost;
}
makeHeap();
init();
int k = ;
for(int i = ;i <= e; i++) {
Node node = deleteMinFromHeap(); /* 总的复杂度 O(e * log v) */
int x = find(node.s); /*O(1)*/
int y = find(node.e);
if (x != y) {
ans += node.cost;
Union(node.s, node.e); /*O(1)*/
k++;
if (k == v) {
break;
}
}
}
if (k != v)
cout << - << endl;
else
cout << ans << endl;
return ;
}
PTA 08-图7 公路村村通 (30分)的更多相关文章
- PTA 7-1 公路村村通 (30分)
PTA 7-1 公路村村通 (30分) 现有村落间道路的统计数据表中,列出了有可能建设成标准公路的若干条道路的成本,求使每个村落都有公路连通所需要的最低成本. 输入格式: 输入数据包括城镇数目正整数N ...
- pta08-图7 公路村村通 (30分)
08-图7 公路村村通 (30分) 现有村落间道路的统计数据表中,列出了有可能建设成标准公路的若干条道路的成本,求使每个村落都有公路连通所需要的最低成本. 输入格式: 输入数据包括城镇数目正整数N ...
- pta 编程题21 公路村村通
其它pta数据结构编程题请参见:pta 题目 这道题考察最小生成树问题,用的是Prim算法. 和Dijkstra算法相比,没有了collect数组,因为dist[v] == 0就代表v被已收录. #i ...
- pat06-图6. 公路村村通(30)
06-图6. 公路村村通(30) 时间限制 400 ms 内存限制 65536 kB 代码长度限制 8000 B 判题程序 Standard 现有村落间道路的统计数据表中,列出了有可能建设成标准公路的 ...
- 7-6 公路村村通(30 分) 【prime】
7-6 公路村村通(30 分) 现有村落间道路的统计数据表中,列出了有可能建设成标准公路的若干条道路的成本,求使每个村落都有公路连通所需要的最低成本. 输入格式: 输入数据包括城镇数目正整数N(≤10 ...
- ACM程序设计选修课——Problem E:(ds:图)公路村村通(Prim)
问题 E: (ds:图)公路村村通 时间限制: 1 Sec 内存限制: 128 MB 提交: 9 解决: 5 题目描述 现有村落间道路的统计数据表中,列出了有可能建设成标准公路的若干条道路的成本, ...
- 7-10 公路村村通(30 分)(最小生成树Prim算法)
7-10 公路村村通(30 分) 现有村落间道路的统计数据表中,列出了有可能建设成标准公路的若干条道路的成本,求使每个村落都有公路连通所需要的最低成本. 输入格式: 输入数据包括城镇数目正整数N(≤1 ...
- PTA 7-1 是否完全二叉搜索树 (30分)
PTA 7-1 是否完全二叉搜索树 (30分) 将一系列给定数字顺序插入一个初始为空的二叉搜索树(定义为左子树键值大,右子树键值小),你需要判断最后的树是否一棵完全二叉树,并且给出其层序遍历的结果. ...
- PTA二叉搜索树的操作集 (30分)
PTA二叉搜索树的操作集 (30分) 本题要求实现给定二叉搜索树的5种常用操作. 函数接口定义: BinTree Insert( BinTree BST, ElementType X ); BinTr ...
随机推荐
- C++的构造函数和析构函数
1.构造函数和析构函数为什么没有返回值? 构造函数和析构函数是两个非常特殊的函数:它们没有返回值.这与返回值为void的函数显然不同,后者虽然也不返回任何值,但还可以让它做点别的事情,而构造函数和析构 ...
- PHP mysql_real_escape_string() 函数
定义和用法 mysql_real_escape_string() 函数转义 SQL 语句中使用的字符串中的特殊字符. 下列字符受影响: \x00 \n \r \ ' " \x1a 如果成功, ...
- 解决Ubuntu14.04下Clementine音乐播放器不能播放wma文件的问题
参考:Ubuntu 14.04 安装深度音乐的方法 问题描述:播放wma文件时提示"GStreamer插件未安装". 解决方法:安装gstreamer-ffmpeg插件即可解决问题 ...
- tortoisesvn的安装与使用
1.下载安装文件,我用的是1.6.同时可以下载一个中文的安装包. 2.我在F盘建立了一个文件夹tortoisesvn,专门用来放置版本目录文件.然后右键这个文件夹,选择tortoisesvn-> ...
- JavaWeb学习总结(十三)——使用Session防止表单重复提交
在平时开发中,如果网速比较慢的情况下,用户提交表单后,发现服务器半天都没有响应,那么用户可能会以为是自己没有提交表单,就会再点击提交按钮重复提交表单,我们在开发中必须防止表单重复提交. 一.表单重复提 ...
- 基于Qt5.x的QCA加解密开源项目的编译过程
记录一下Qt5.x下的QCA的编译过程 需要注意的几点 针对windows环境 1.编译QCA源码前,必须先安装openssl二进制文件 2.需要安装好vs2008等 ( 64-bit Visual ...
- Android 各个版本WebView
转载请注明出处 http://blog.csdn.net/typename/ powered by miechal zhao : miechalzhao@gmail.com 前言: 根据Googl ...
- C++构造函数,复制构造函数和析构函数专题
链接:http://wenku.baidu.com/view/d9316c0e52ea551810a6872a.html 本文作者:黄邦勇帅本文是学习 C++中的最基本的内容,因此学习 C++就应全部 ...
- write & read a sequence file(基于全新2.2.0API)
write & read a sequence file write & read a sequence file import java.io.IOException; import ...
- Web.config配置文件详解(新手必看)
花了点时间整理了一下ASP.NET Web.config配置文件的基本使用方法.很适合新手参看,由于Web.config在使用很灵活,可以自定义一些节点.所以这里只介绍一些比较常用的节点. <? ...