现有村落间道路的统计数据表中,列出了有可能建设成标准公路的若干条道路的成本,求使每个村落都有公路连通所需要的最低成本。

输入格式:

输入数据包括城镇数目正整数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分)的更多相关文章

  1. PTA 7-1 公路村村通 (30分)

    PTA 7-1 公路村村通 (30分) 现有村落间道路的统计数据表中,列出了有可能建设成标准公路的若干条道路的成本,求使每个村落都有公路连通所需要的最低成本. 输入格式: 输入数据包括城镇数目正整数N ...

  2. pta08-图7 公路村村通 (30分)

    08-图7 公路村村通   (30分) 现有村落间道路的统计数据表中,列出了有可能建设成标准公路的若干条道路的成本,求使每个村落都有公路连通所需要的最低成本. 输入格式: 输入数据包括城镇数目正整数N ...

  3. pta 编程题21 公路村村通

    其它pta数据结构编程题请参见:pta 题目 这道题考察最小生成树问题,用的是Prim算法. 和Dijkstra算法相比,没有了collect数组,因为dist[v] == 0就代表v被已收录. #i ...

  4. pat06-图6. 公路村村通(30)

    06-图6. 公路村村通(30) 时间限制 400 ms 内存限制 65536 kB 代码长度限制 8000 B 判题程序 Standard 现有村落间道路的统计数据表中,列出了有可能建设成标准公路的 ...

  5. 7-6 公路村村通(30 分) 【prime】

    7-6 公路村村通(30 分) 现有村落间道路的统计数据表中,列出了有可能建设成标准公路的若干条道路的成本,求使每个村落都有公路连通所需要的最低成本. 输入格式: 输入数据包括城镇数目正整数N(≤10 ...

  6. ACM程序设计选修课——Problem E:(ds:图)公路村村通(Prim)

    问题 E: (ds:图)公路村村通 时间限制: 1 Sec  内存限制: 128 MB 提交: 9  解决: 5 题目描述 现有村落间道路的统计数据表中,列出了有可能建设成标准公路的若干条道路的成本, ...

  7. 7-10 公路村村通(30 分)(最小生成树Prim算法)

    7-10 公路村村通(30 分) 现有村落间道路的统计数据表中,列出了有可能建设成标准公路的若干条道路的成本,求使每个村落都有公路连通所需要的最低成本. 输入格式: 输入数据包括城镇数目正整数N(≤1 ...

  8. PTA 7-1 是否完全二叉搜索树 (30分)

    PTA 7-1 是否完全二叉搜索树 (30分) 将一系列给定数字顺序插入一个初始为空的二叉搜索树(定义为左子树键值大,右子树键值小),你需要判断最后的树是否一棵完全二叉树,并且给出其层序遍历的结果. ...

  9. PTA二叉搜索树的操作集 (30分)

    PTA二叉搜索树的操作集 (30分) 本题要求实现给定二叉搜索树的5种常用操作. 函数接口定义: BinTree Insert( BinTree BST, ElementType X ); BinTr ...

随机推荐

  1. 17款code review工具

    本文是码农网原创翻译,转载请看清文末的转载要求,谢谢合作! 好的代码审查器可以大大地帮助程序员提高代码质量,减少错误几率. 虽然现在市场上有许多可用的代码审查工具,但如何挑选也是一个艰巨的任务.在咨询 ...

  2. aircrack-ng on OSX 从零开始之安装

    今天在知乎上看到了Evil1m0在知乎上写的一个关于无线网入侵的帖子,激起我也想折腾一下想法.其实这个想法已经由来已久了.如今WIFI遍地都有,这里面的安全隐患我真心觉得太大.实在需要舆论来给大家普及 ...

  3. delphi xe5 android 开发数据访问手机端 解决乱码的办法

    经过测试,将sqlserver里的字段由varchar 或者char  改为  nvarchar 或者nchar 然后在手机端的clientdataset 增加字段的时候数据类型选择widestrin ...

  4. 关于 Java 性能监控您不知道的 5 件事,第 1 部分

    责怪糟糕的代码(或不良代码对象)并不能帮助您发现瓶颈,提高 Java? 应用程序速度,猜测也不能帮您解决.Ted Neward 引导您关注 Java 性能监控工具,从5 个技巧开始,使用Java 5 ...

  5. JS获取IP、MAC和主机名的几种方法

    方法一(只针对IE且客户端的IE允许AcitiveX运行,通过平台:XP,SERVER03,2000): 获取客户端IP. <HTML> <HEAD> <TITLE> ...

  6. Oracle SQL tuning 步骤

    Oracle SQL tuning 步骤 SQL是的全称是Structured Query Language(结构化查询语言).SQL是一个在80年代中期被使用的工业标准数据库查询语言.不要把SQL语 ...

  7. Access forbidden! XAMPP虚拟主机的问题

    XAMPP Control Panel v3.2.1添加虚拟主机出现 Access forbidden! You don't have permission to access the request ...

  8. 禁用nginx的access日志

    修改nginx.conf 找到access_log: access_log /dev/null; 或者access_log off

  9. [状压dp]经典TSP

    0出发 每个顶点经过一次 回到0 最小花费. O($n^2 \times 2^n$) 记忆化搜索: // s: 已经访问过的节点状态 v: 出发位置 int dfs(int s, int v) { ) ...

  10. js设置radio选中

    在页面数据绑定时,经常会遇到给radio设置选中,以下是我写的js方法,经测试可以使用.欢迎拍砖 <html> <head> <script type="tex ...