38-布线问题
内存限制:64MB
时间限制:1000ms
Special Judge: No
accepted:5
submit:11
题目描述:
南阳理工学院要进行用电线路改造,现在校长要求设计师设计出一种布线方式,该布线方式需要满足以下条件:
1、把所有的楼都供上电。
2、所用电线花费最少
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模板):
1 int prim() 2 { 3 int cnt = 0, pos = 1, my_weight[n+1], my_book[n+1] = {1, 1}; // cnt表示最小的布线情况 4 for(int i = 1; i <= n; ++ i) 5 if(!my_book[i]) 6 my_weight[i] = my_map[pos][i]; 7 for(int i = 1; i < n; ++ i) 8 { 9 int my_min = MAXNUM; 10 for(int j = 1; j <= n; ++ j) 11 { 12 if(!my_book[j] && my_weight[j] < my_min) 13 { 14 my_min = my_weight[j]; 15 pos = j; 16 } 17 } 18 cnt += my_min; 19 my_book[pos] = 1; 20 for(int j = 1; j <= n; ++ j) 21 { 22 if(!my_book[j] && my_weight[j] > my_map[j][pos]) 23 my_weight[j] = my_map[j][pos]; 24 } 25 } 26 return cnt; 27 }
C/C++代码实现(AC):
1 #include <bits/stdc++.h> 2 3 using namespace std; 4 const int MAXN = 505; 5 const int MAXNUM = 0x3f3f3f3f; 6 int my_map[MAXN][MAXN], n, m, my_line[MAXN]; 7 8 int prim() 9 { 10 int cnt = 0, pos = 1, my_weight[n+1], my_book[n+1] = {1, 1}; // cnt表示最小的布线情况 11 for(int i = 1; i <= n; ++ i) 12 if(!my_book[i]) 13 my_weight[i] = my_map[pos][i]; 14 for(int i = 1; i < n; ++ i) 15 { 16 int my_min = MAXNUM; 17 for(int j = 1; j <= n; ++ j) 18 { 19 if(!my_book[j] && my_weight[j] < my_min) 20 { 21 my_min = my_weight[j]; 22 pos = j; 23 } 24 } 25 cnt += my_min; 26 my_book[pos] = 1; 27 for(int j = 1; j <= n; ++ j) 28 { 29 if(!my_book[j] && my_weight[j] > my_map[j][pos]) 30 my_weight[j] = my_map[j][pos]; 31 } 32 } 33 return cnt; 34 } 35 36 int main() 37 { 38 int t; 39 scanf("%d", &t); 40 while(t --) 41 { 42 scanf("%d%d", &n, &m); 43 for(int i = 1; i <= n; ++ i) 44 for(int j = 1; j <= n; ++ j) 45 my_map[i][j] = MAXNUM; 46 for(int i = 0; i < m; ++ i) 47 { 48 int a, b, c; 49 scanf("%d%d%d", &a, &b, &c); 50 my_map[a][b] = my_map[b][a] = c; 51 } 52 53 for(int i = 0; i < n; ++ i) 54 scanf("%d", &my_line[i]); 55 sort(my_line, my_line + n, less<int>()); 56 printf("%d ", my_line[0] + prim()); 57 } 58 return 0; 59 }