38-布线问题

内存限制:64MB
时间限制:1000ms
Special Judge: No

accepted:5
submit:11

题目描述:

南阳理工学院要进行用电线路改造,现在校长要求设计师设计出一种布线方式,该布线方式需要满足以下条件:
1、把所有的楼都供上电。
2、所用电线花费最少

输入描述:

第一行是一个整数n表示有n组测试数据。(n<5)
每组测试数据的第一行是两个整数v,e.
v表示学校里楼的总个数(v<=500)
随后的e行里,每行有三个整数a,b,c表示a与b之间如果建铺设线路花费为c(c<=100)。(哪两栋楼间如果没有指明花费,则表示这两栋楼直接连通需要费用太大或者不可能连通)
随后的1行里,有v个整数,其中第i个数表示从第i号楼接线到外界供电设施所需要的费用。( 0<e<v*(v-1)/2 )
(楼的编号从1开始),由于安全问题,只能选择一个楼连接到外界供电设备。
数据保证至少存在一种方案满足要求。

输出描述:

每组测试数据输出一个正整数,表示铺设满足校长要求的线路的最小花费。

样例输入:

复制

1
4 6
1 2 10
2 3 10
3 1 10
1 4 1
2 4 1
3 4 1
1 3 5 6

样例输出:

4

分析:
  ①、他要求的布线情况(因为一定有结果)就是求图的最短路径问题
  ②、我们可以考虑右prim算法
    1、prim算法就是由任意一个点开始找最短的路径
    2、在前一个的基础上我们可以得到两个点且改两个点已经连接上
    3、现在我们要找的就是经过第一个或第二个点的最小路径
    4、依次循环直到遍历所有的点
 ③、从外面连入的线我们直接根据升序排序,再取最小的值
 ④、两者相加即为结果 核心代码(prim模板):
 int prim()
{
int cnt = , pos = , my_weight[n+], my_book[n+] = {, }; // cnt表示最小的布线情况
for(int i = ; i <= n; ++ i)
if(!my_book[i])
my_weight[i] = my_map[pos][i];
for(int i = ; i < n; ++ i)
{
int my_min = MAXNUM;
for(int j = ; j <= n; ++ j)
{
if(!my_book[j] && my_weight[j] < my_min)
{
my_min = my_weight[j];
pos = j;
}
}
cnt += my_min;
my_book[pos] = ;
for(int j = ; j <= n; ++ j)
{
if(!my_book[j] && my_weight[j] > my_map[j][pos])
my_weight[j] = my_map[j][pos];
}
}
return cnt;
}

C/C++代码实现(AC):

 #include <bits/stdc++.h>

 using namespace std;
const int MAXN = ;
const int MAXNUM = 0x3f3f3f3f;
int my_map[MAXN][MAXN], n, m, my_line[MAXN]; int prim()
{
int cnt = , pos = , my_weight[n+], my_book[n+] = {, }; // cnt表示最小的布线情况
for(int i = ; i <= n; ++ i)
if(!my_book[i])
my_weight[i] = my_map[pos][i];
for(int i = ; i < n; ++ i)
{
int my_min = MAXNUM;
for(int j = ; j <= n; ++ j)
{
if(!my_book[j] && my_weight[j] < my_min)
{
my_min = my_weight[j];
pos = j;
}
}
cnt += my_min;
my_book[pos] = ;
for(int j = ; j <= n; ++ j)
{
if(!my_book[j] && my_weight[j] > my_map[j][pos])
my_weight[j] = my_map[j][pos];
}
}
return cnt;
} int main()
{
int t;
scanf("%d", &t);
while(t --)
{
scanf("%d%d", &n, &m);
for(int i = ; i <= n; ++ i)
for(int j = ; j <= n; ++ j)
my_map[i][j] = MAXNUM;
for(int i = ; i < m; ++ i)
{
int a, b, c;
scanf("%d%d%d", &a, &b, &c);
my_map[a][b] = my_map[b][a] = c;
} for(int i = ; i < n; ++ i)
scanf("%d", &my_line[i]);
sort(my_line, my_line + n, less<int>());
printf("%d\n", my_line[] + prim());
}
return ;
}

最新文章

  1. PHP常量、变量作用域详解(一)
  2. EasyUI的combobox控件使用onchange 问题
  3. vncserver安装
  4. C#生成注册码
  5. golang flag包简单例子
  6. c# ReaderWriterLock类
  7. 14.5.2.2 autocommit, Commit, and Rollback
  8. 从ConcurrentHashMap的演进看Java多线程核心技术 Java进阶(六)
  9. 怎样才能收集到所有开发人员的blog(待续&hellip;)
  10. Vscode新建html文件
  11. Windows中的备份和还原
  12. html5中如何更改、去掉input type默认样式
  13. linux简单优化
  14. 解决多个div左浮动后不换行问题
  15. mysqldump备份与恢复笔记
  16. hdu6444 2018中国大学生程序设计竞赛 - 网络选拔赛 1007 Neko&#39;s loop
  17. 用@resource注解方式完成属性装配
  18. 利用python实现新浪微博爬虫
  19. 廖雪峰的python学习网址
  20. 使用Git将码云上的代码Clone至本地

热门文章

  1. 怎样快速找到某一行代码的git提交记录
  2. httprunner-1-linux下搭建hrun(上)
  3. JavaScript 变量作用域和声明提升
  4. SQL手工注入方法
  5. python模块的导入详解
  6. Java多线程编程(五)定时器Timer
  7. 这一次,终于系统的学习了 JVM 内存结构
  8. Oracle Dorp 表数据恢复
  9. 《吊打面试官》系列-Redis哨兵、持久化、主从、手撕LRU
  10. centos下docker离线部署