洛谷P3905 道路重建

题目描述

从前,在一个王国中,在 $n$ 个城市间有 $m$ 条道路连接,而且任意两个城市之间至多有一条道路直接相连。在经过一次严重的战争之后,有 $d$ 条道路被破坏了。国王想要修复国家的道路系统,现在有两个重要城市 $A$ 和 $B$ 之间的交通中断,国王希望尽快的恢复两个城市之间的连接。你的任务就是修复一些道路使 $A$ 与 $B$ 之间的连接恢复,并要求修复的道路长度最小。

输入格式

输入文件第一行为一个整数 $n\ (2<n\le 100)$,表示城市的个数。这些城市编号从 $1$ 到 $n$。

第二行为一个整数 $m\ (n-1\le m\le \dfrac{1}{2}n(n-1))$,表示道路的数目。

接下来的 $m$ 行,每行 $3$ 个整数 $i,j,k\ (1 \le i,j \le n,i\neq j,0<k \le 100)$,表示城市 $i$ 与 $j$ 之间有一条长为 $k$ 的道路相连。

接下来一行为一个整数 $d\ (1\le d\le m)$,表示战后被破坏的道路的数目。在接下来的 $d$ 行中,每行两个整数 $i$ 和 $j$,表示城市 $i$ 与 $j$ 之间直接相连的道路被破坏。

最后一行为两个整数 $A$ 和 $B$,代表需要恢复交通的两个重要城市。

输出格式

输出文件仅一个整数,表示恢复 $A$ 与 $B$ 间的交通需要修复的道路总长度的最小值。

样例 #1

样例输入 #1

3 2 1 2 1 2 3 2 1 1 2 1 3

样例输出 #1

1

题解

#include <bits/stdc++.h> #define AC return 0 using namespace std; int n, m, k, s, f, h[105][105], d[105][105]; void floyd(int n) { for (int k = 1; k <= n; k++) for (int i = 1; i <= n; i++) for (int j = 1; j <= n; j++) h[i][j] = min(h[i][j], h[i][k] + h[k][j]); } int main() { memset(h, 0x3f, sizeof(h)); cin >> n >> m; for (int i = 1; i <= m; i++) { int u, v; cin >> u >> v >> d[u][v]; d[v][u] = d[u][v]; h[v][u] = h[u][v] = 0; } cin >> k; for (int i = 1; i <= k; i++) { int u, v; cin >> u >> v; h[u][v] = h[v][u] = d[u][v]; } cin >> s >> f; floyd(n); cout << h[s][f] << endl; AC; }