CCF CSP 201609-4.交通规划

问题描述

  G国国王来中国参观后,被中国的高速铁路深深的震撼,决定为自己的国家也建设一个高速铁路系统。
  建设高速铁路投入非常大,为了节约建设成本,G国国王决定不新建铁路,而是将已有的铁路改造成高速铁路。现在,请你为G国国王提供一个方案,将现有的一部分铁路改造成高速铁路,使得任何两个城市间都可以通过高速铁路到达,而且从所有城市乘坐高速铁路到首都的最短路程和原来一样长。请你告诉G国国王在这些条件下最少要改造多长的铁路。

输入格式

  输入的第一行包含两个整数n, m,分别表示G国城市的数量和城市间铁路的数量。所有的城市由1到n编号,首都为1号。
  接下来m行,每行三个整数a, b, c,表示城市a和城市b之间有一条长度为c的双向铁路。这条铁路不会经过ab以外的城市。

输出格式

  输出一行,表示在满足条件的情况下最少要改造的铁路长度。

样例输入

4 5
1 2 4
1 3 5
2 3 2
2 4 3
3 4 2

样例输出

11

评测用例规模与约定

  对于20%的评测用例,1 ≤ n ≤ 10,1 ≤ m ≤ 50;
  对于50%的评测用例,1 ≤ n ≤ 100,1 ≤ m ≤ 5000;
  对于80%的评测用例,1 ≤ n ≤ 1000,1 ≤ m ≤ 50000;
  对于100%的评测用例,1 ≤ n ≤ 10000,1 ≤ m ≤ 100000,1 ≤ a, b ≤ n,1 ≤ c ≤ 1000。输入保证每个城市都可以通过铁路达到首都。


分析:

本题考察单源最短路径问题,可以采用dijkstra算法求解。

本题要求的是最少要改造的铁路长度,当出现多条最短路径时,应该选择较短的边。

例如,在样例中,1-3-4和1-2-4均为1和4之间的最短路径,但是2-4的长度为3,而3-4的长度为2,故应选择3-4。

1
2
3
4
5
6
7
 1———————(4)——————2
| / |
| / |
(5) --——(2)——- (3)
| / |
| / |
3———————(2)-—————4

使用数组cost存储点u与其前一个点之间的长度。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
#include <cstdio>
#include <climits>
#include <vector>
#include <algorithm>
using namespace std;

typedef struct Node {
int v, dist;
Node(int _v, int _dist) {
v = _v;
dist = _dist;
}
} Edge;

const int MAXN = 10001;

// 使用邻接表存储的图
vector<Edge> graph[MAXN];
int cost[MAXN];
int n;
int d[MAXN];
bool visited[MAXN] = { false };

int dijkstra(int s) {
fill(d, d + n + 1, INT_MAX);
fill(cost, cost + n + 1, INT_MAX);
d[s] = 0;
cost[s] = 0;
// 最少要改造的铁路长度
int result = 0;
for (int i = 0; i < n; i++) {
int u = -1, min = INT_MAX;
for (int j = 1; j <= n; j++) {
if (!visited[j] && d[j] < min) {
u = j;
min = d[j];
}
}
result += cost[u];
visited[u] = true;
for (int j = 0; j < graph[u].size(); j++) {
int v = graph[u][j].v;
if (!visited[v] && d[u] + graph[u][j].dist < d[v]) {
d[v] = d[u] + graph[u][j].dist;
cost[v] = graph[u][j].dist;
} else if (d[u] + graph[u][j].dist == d[v]
&& graph[u][j].dist < cost[v]) {
// 最短路径相同时,长度较小的边对总长度的影响更小
cost[v] = graph[u][j].dist;
}
}
}
return result;
}

int main() {
int m;
scanf("%d %d", &n, &m);

int u, v, dist;
while (m--) {
scanf("%d %d %d", &u, &v, &dist);
graph[u].push_back(Edge(v, dist));
graph[v].push_back(Edge(u, dist));
}

dist = dijkstra(1);
printf("%d\n", dist);
return 0;
}

----------本文结束感谢您的阅读----------
坚持原创技术分享,您的支持将鼓励我继续创作!