题目描述
麦克找了个新女朋友,玛丽卡对他非常恼火并伺机报复。
因为她和他们不住在同一个城市,因此她开始准备她的长途旅行。
在这个国家中每两个城市之间最多只有一条路相通,并且我们知道从一个城市到另一个城市路上所需花费的时间。
麦克在车中无意中听到有一条路正在维修,并且那儿正堵车,但没听清楚到底是哪一条路。无论哪一条路正在维修,从玛丽卡所在的城市都能到达麦克所在的城市。
玛丽卡将只从不堵车的路上通过,并且她将按最短路线行车。麦克希望知道在最糟糕的情况下玛丽卡到达他所在的城市需要多长时间,这样他就能保证他的女朋友离开该城市足够远。
编写程序,帮助麦克找出玛丽卡按最短路线通过不堵车道路到达他所在城市所需的最长时间(用分钟表示)。
输入格式
第一行有两个用空格隔开的数NN和MM,分别表示城市的数量以及城市间道路的数量。1≤N≤1000,1≤M≤N \times (N-1)/21≤N≤1000,1≤M≤N×(N−1)/2。城市用数字1-N1−N标识,麦克在城市11中,玛丽卡在城市NN中。
接下来的MM行中每行包含三个用空格隔开的数A,B,VA,B,V。其中1≤A,B≤N,1≤V≤10001≤A,B≤N,1≤V≤1000。这些数字表示在AA和城市BB中间有一条双行道,并且在VV分钟内是就能通过。
输出格式
一行,写出用分钟表示的最长时间,在这段时间中,无论哪条路在堵车,玛丽卡应该能够到达麦克处,如果少于这个时间的话,则必定存在一条路,该条路一旦堵车,玛丽卡就不能够赶到麦克处。
输入输出样例
输入 #15 7 1 2 8 1 4 10 2 3 9 2 4 10 2 5 1 3 4 7 3 5 10输出 #1
27
暴力枚举删掉每一条边,然后跑多遍SPFA
#include <iostream> #include <cstdio> #include <algorithm> #include <queue> #include <vector> #include <cstring> using namespace std; typedef pair<int, int> P; priority_queue<P, vector<P>, greater<P> > Q; const int maxedge = (1e3*1e3+3) * 2; const int maxnode = 1e3+3; int n, m, fir[maxnode], nx[maxedge], dis[maxnode], cnt, Ans; int u[maxedge], v[maxedge], w[maxedge], pre[maxnode]; bool use[maxedge], cut[maxnode][maxnode], mark; inline void addedge(int x, int y, int z) { nx[++cnt] = fir[x]; fir[x] = cnt; u[cnt] = x, v[cnt] = y, w[cnt] = z; } inline void Dijkstra() { fill(dis+1, dis+1+n, 1234567890); Q.push(P(0, 1)); dis[1] = 0; int k; P x; while (!Q.empty()) { x = Q.top(); Q.pop(); if(x.first > dis[x.second]) continue; k = fir[x.second]; while (k != -1) { if(x.first + w[k] < dis[v[k]] && !cut[u[k]][v[k]]) { if(!mark) pre[v[k]] = u[k]; dis[v[k]] = x.first + w[k]; Q.push(P(dis[v[k]], v[k])); } k = nx[k]; } } } int main() { scanf("%d%d", &n, &m); memset(fir, -1, sizeof(fir)); int x, y, z; for(int i=1; i<=m; i++) { scanf("%d%d%d", &x, &y, &z); addedge(x, y, z); addedge(y, x, z); } Dijkstra(); mark = 1; for(int i=n; i!=1; i = pre[i]) { cut[pre[i]][i] = 1; cut[i][pre[i]] = 1; Dijkstra(); cut[pre[i]][i] = 0; cut[i][pre[i]] = 0; Ans = max(Ans, dis[n]); } printf("%d", Ans); }