【题意】:给出一个无向图,Harry Potter的目的是从1走到n,而Voldemort为了阻止他,使用魔法毁掉了图中的一条边,问最坏情况下Harry要走的最短路是多少。

【题解】:先考虑这么一个问题,如果不允许毁掉图中的边,那么求一次最短路即可。回到初始问题,这是一个最小值最大化的问题,显然最坏情况下肯定是删掉最短路上的一条边,这个很容易理解吧。具体做法:先求一次最短路并记录最短路径,枚举删掉最短路上的每一条边,再求最短路,这些结果中最大值就是最后答案;如果某次删边使得1无法到达n,那么可以跳出枚举,因为这已经是最坏的情况。

【代码】:
 1 #include "iostream"
 2 #include "cstdio"
 3 #include "cstring"
 4 #include "queue"
 5 using namespace std;
 6 #define maxn 1005
 7 #define maxm 100500
 8 const int inf = 1 << 30;
 9 int n, m, s, x;
10 int eh[maxn], dist[maxn], pre[maxn], p[maxn], tot;
11 bool visit[maxn], flag;
12 struct Edge {
13     int u, v, w, next;
14 }et[maxm];
15 
16 void init() {
17     tot = 0;
18     memset(eh, -1sizeof(eh));
19 }
20 
21 void addedge(int u, int v, int w) {
22     Edge e = {u, v, w, eh[u]};
23     et[tot] = e;
24     eh[u] = tot++;
25 }
26 
27 int spfa() {
28     queue<int> que;
29     fill(dist, dist + maxn, inf);
30     memset(visit, falsesizeof(visit));
31     dist[s] = 0, visit[s] = true;
32     que.push(s);
33     while(!que.empty()) {
34         int u = que.front();
35         que.pop();
36         visit[u] = false;
37         for(int i = eh[u]; i != -1; i = et[i].next) {
38             int v = et[i].v, w = et[i].w;
39             if(dist[u] + w < dist[v] && i != x) {
40                 dist[v] = dist[u] + w;
41                 if(x == -1) pre[v] = i, p[v] = u;
42                 if(!visit[v]) {
43                     que.push(v);
44                     visit[v] = true;
45                 }
46             }
47         }
48     }
49     return dist[n];
50 }
51 
52 int solve() {
53     x = -1;
54     int ans = spfa();
55     if(ans == inf) return -1;
56     for(int i = n; i != s; i = p[i]) {
57         x = pre[i];
58         ans = max(ans, spfa());
59         if(ans == inf) return -1;
60     }
61     return ans;
62 }
63 
64 int main() {
65     int T;
66     scanf("%d"&T);
67     while(T--) {
68         scanf("%d%d"&n, &m);
69         init();
70         s = 1;
71         for(int i = 0; i < m; i++) {
72             int u, v, w;
73             scanf("%d%d%d"&u, &v, &w);
74             addedge(u, v, w);
75             addedge(v, u, w);
76         }
77         int ans = solve();
78         printf("%d\n", ans);
79     }
80     return 0;
81 }