nyoj 38-布线问题(prim, sort)

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模板):

 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 }
原文地址:https://www.cnblogs.com/GetcharZp/p/9074099.html