问题描述
G国国王来中国参观后,被中国的高速铁路深深的震撼,决定为自己的国家也建设一个高速铁路系统。
建设高速铁路投入非常大,为了节约建设成本,G国国王决定不新建铁路,而是将已有的铁路改造成高速铁路。现在,请你为G国国王提供一个方案,将现有的一部分铁路改造成高速铁路,使得任何两个城市间都可以通过高速铁路到达,而且从所有城市乘坐高速铁路到首都的最短路程和原来一样长。请你告诉G国国王在这些条件下最少要改造多长的铁路。
输入格式
输入的第一行包含两个整数n, m,分别表示G国城市的数量和城市间铁路的数量。所有的城市由1到n编号,首都为1号。
接下来m行,每行三个整数a, b, c,表示城市a和城市b之间有一条长度为c的双向铁路。这条铁路不会经过a和b以外的城市。
输出格式
输出一行,表示在满足条件的情况下最少要改造的铁路长度。
样例输入
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。输入保证每个城市都可以通过铁路达到首都。
思路说明
这是一个最短路径算法,但是要在某点出现最短路径长度相同的时候,选择最短的前一段路径。
import java.util.ArrayList;
import java.util.PriorityQueue;
import java.util.Queue;
import java.util.Scanner;
public class Java_201609_4 {
static ArrayList<Edge>[] map;
static Queue<Node> q;
static boolean[] vis;
static int[] dis;
static int[] cost;
static int n;
public static void main(String[] args) {
Scanner sin = new Scanner(System.in);
n = sin.nextInt();
int m = sin.nextInt();
map = new ArrayList[n + 1];
q = new PriorityQueue();
vis = new boolean[n + 1];
dis = new int[n + 1];
cost = new int[n + 1];
for (int i = 0; i <= n; i++) {
map[i] = new ArrayList();
dis[i] = 0x3f3f3f;
}
for (int j = 0; j < m; j++) {
int start = sin.nextInt();
int end = sin.nextInt();
int weight = sin.nextInt();
map[start].add(new Edge(end, weight));
map[end].add(new Edge(start, weight));
}
Dijkstra(1);
int sum = 0;
for (int k = 2; k <= n; k++) {
sum += cost[k];
}
System.out.println(sum);
}
static void Dijkstra(int start) {
vis[0] = true;
q.offer(new Node(start, 0));
while (!q.isEmpty()) {
Node tmp = q.poll();
if (!vis[tmp.end]) {
vis[tmp.end] = true;
for (int j = 0; j < map[tmp.end].size(); j++) {
int weight = tmp.weight + map[tmp.end].get(j).weight;
int end = map[tmp.end].get(j).end;
int co = map[tmp.end].get(j).weight;
Edge e = new Edge(tmp.end, co);
map[end].remove(e);
if (weight < dis[end]) {
dis[end] = weight;
cost[end] = weight;
q.offer(new Node(end, dis[end]));
}
if (weight == dis[end]) {
cost[end] = Math.min(cost[end], co);
}
}
}
}
}
static class Node implements Comparable {
int end;
int weight;
Node(int end, int weight) {
this.end = end;
this.weight = weight;
}
@Override
public int compareTo(Object arg0) {
return this.weight - ((Node) arg0).weight;
}
}
static class Edge {
int end;
int weight;
Edge(int end, int weight) {
this.end = end;
this.weight = weight;
}
@Override
public boolean equals(Object obj) {
Edge other = (Edge) obj;
if (this.end == other.end && this.weight == other.weight) {
return true;
}
return false;
}
}
}