题目来源:HDU 1595 find the longest of the shortest
题意:n个点m条边的无向图 有一条路是不能走的 求从1到n最短路的最大值
思路:首先求出最短路 如果坏掉的那条路不在最短路上 那么最短路是不会变大的 所以枚举最短路上的n-1条边 每次把这条路设为正无穷 在做最短路 取最大值
一次Dijkstra的最短路的复杂度是mlogn n次最短路的复杂度是nmlogn
#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() { while(scanf("%d %d", &n, &m) != EOF) { 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) continue; if(ans == -1 || ans < d[n]) ans = d[n]; } printf("%d\n", ans); } return 0; }