题目来源:HDU 3986 Harry Potter and the Final Battle
题意:哈利波特要从1到n 不过敌人可以破坏一条边 求最坏的情况下到达n需要的最短时间 不能到达输出-1
思路:和上一题差不多 每次枚举最短路上的边 然后去掉该条边在做最短路 因为是无向的 不要忘记把它的反向边也删除
上一题一定有解 这题不一定 如果去掉一条边后无法到达n那么输出-1 因为敌人足够聪明
#include <cstdio> #include <cstring> #include <queue> #include <vector> using namespace std; const int maxn = 1010; struct edge { int u, v, w; }a[maxn*maxn]; int n, m, num; struct HeapNode { int u, d; bool operator < (const HeapNode& rhs) const { return d > rhs.d; } }; vector <edge> edges; vector <int> G[maxn]; int d[maxn]; int p[maxn]; bool vis[maxn]; void Dijkstra(int s) { for(int i = 0; i <= n; i++) d[i] = 999999999; d[1] = 0; memset(vis, false, sizeof(vis)); if(s) memset(p, -1, sizeof(p)); priority_queue <HeapNode> Q; HeapNode x; x.u = 1; x.d = 0; Q.push(x); while(!Q.empty()) { x = Q.top();Q.pop(); int u = x.u; if(vis[u]) continue; vis[u] = true; for(int i = 0; i < G[u].size(); i++) { edge e = edges[G[u][i]]; int v = e.v; if(d[v] > x.d + e.w) { if(s) p[v] = G[u][i]; d[v] = x.d + e.w; HeapNode xx; xx.u = v; xx.d = d[v]; Q.push(xx); } } } } void AddEdge(int u, int v, int w) { edge x; x.u = u; x.v = v; x.w = w; edges.push_back(x); x.u = v; x.v = u; edges.push_back(x); num = edges.size(); G[u].push_back(num-2); G[v].push_back(num-1); } int main() { int T; scanf("%d", &T); while(T--) { scanf("%d %d", &n, &m); for(int i = 0; i <= n; i++) G[i].clear(); edges.clear(); for(int i = 0; i < m; i++) { scanf("%d %d %d", &a[i].u, &a[i].v, &a[i].w); AddEdge(a[i].u, a[i].v, a[i].w); } Dijkstra(1); int ans = -1; int pos = p[n]; while(pos != -1) { //printf("%d %d\n", pos, pos^1); int w1 = edges[pos].w; int w2 = edges[pos^1].w; edges[pos].w = 999999999; edges[pos^1].w = 999999999; Dijkstra(0); edges[pos].w = w1; edges[pos^1].w = w2; pos = p[edges[pos].u]; if(d[n] == 999999999) { ans = -1;//有一次不能到达 就输出-1 break; } if(ans == -1 || ans < d[n]) ans = d[n]; } printf("%d\n", ans); } return 0; }