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

输入格式:

输入数据包括城镇数目正整数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. uva 104 Bandwidth

    题意: 给一个图, 将其节点以任一序列排列. 1)计算每个节点距离相邻节点的最大距离 dis[i] 2)计算出当前序列中, 所有节点的dis[i], 并求出最大的dis[i] : max_dis 求最 ...

  2. java代码整理---正则表达式

    1. 邮箱验证 : package javaRegx2016311; import java.util.regex.Matcher; import java.util.regex.Pattern; p ...

  3. 客户端动态调用cxf websevice 异常

    三月 30, 2014 10:06:40 上午 org.apache.cxf.common.jaxb.JAXBUtils logGeneratedClassNames 信息: Created clas ...

  4. HDU3368+枚举

    题意看不懂的直接看百度百科对黑白棋的解释... 做法:分情况讨论,一共8个方向. /* 搜索 */ #include<stdio.h> #include<string.h> ; ...

  5. Joda-Time

    任何企业应用程序都需要处理时间问题.应用程序需要知道当前的时间点和下一个时间点,有时它们还必须计算这两个时间点之间的路径.使用 JDK 完成这项任务将非常痛苦和繁琐.现在来看看 Joda Time,一 ...

  6. 令人头疼的clientTop、scrollTop、offsetTop

    1.网络上流传的图片 2.稍微容易理解点的示意图 参考链接:http://blog.csdn.net/lidiansheng/article/details/7950751 3.言简意赅的示意图 4. ...

  7. ActionBar官方教程(9)ActionBar的顶部tab模式(注意,已经被弃用)

    This interface is deprecated.Action bar navigation modes are deprecated and not supported by inline ...

  8. WCF - Windows Service Hosting

    WCF - Windows Service Hosting The operation of Windows service hosting is a simple one. Given below ...

  9. HDU4739Zhuge Liang's Mines(状压)

    链接 预处理出只有四个1的情况存入数组中 然后状压下 #include <iostream> #include<cstdio> #include<cstring> ...

  10. poj2817WordStack(状压)

    链接 与上题类似  预处理一下各字符串之间最大的相同字符数就可以 注意dp要初始为负无穷 #include <iostream> #include<cstdio> #inclu ...