一个城市中有n个站m条线路(指直接相连接u-v),也就是和城市地铁一样,在某个站换线需要花额外的时间,求1号站到n号站的最短时间消耗。
猛的一看就是普通的最短路问题,但是实际需要改变很多,不能单纯的按照原来的方式求解dis[v]表示到v的最小时间花费。
因为你无法知道这个最小值是由哪条线路过来的,会直接影响后面的换线时间消耗。所以我们纪录走i号线到v的最小时间,
这样就能明白起最小时间和哪条线路了。
dis[i],编号i的线路由u到v,那么dis[i]就表示1号站到v最后一天路径是i时的最小时间花费。
/*****************************************
Author :Crazy_AC(JamesQi)
Time :2016
File Name :
*****************************************/
// #pragma comment(linker, "/STACK:1024000000,1024000000")
#include <iostream>
#include <algorithm>
#include <iomanip>
#include <sstream>
#include <string>
#include <stack>
#include <queue>
#include <deque>
#include <vector>
#include <map>
#include <set>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <cstdlib>
#include <climits>
using namespace std;
#define MEM(x,y) memset(x, y,sizeof x)
#define pk push_back
#define lson rt << 1
#define rson rt << 1 | 1
#define bug cout << "BUG HERE\n"
#define debug(x) cout << #x << " = " << x << endl
#define ALL(v) (v).begin(), (v).end()
#define lowbit(x) ((x)&(-x))
#define Unique(x) sort(ALL(x)); (x).resize(unique(ALL(x)) - (x).begin())
#define BitOne(x) __builtin_popcount(x)
#define showtime printf("time = %.15f\n",clock() / (double)CLOCKS_PER_SEC)
#define Rep(i, l, r) for (int i = l;i <= r;++i)
#define Rrep(i, r, l) for (int i = r;i >= l;--i)
typedef long long LL;
typedef unsigned long long ULL;
typedef pair<int,int> ii;
typedef pair<ii,int> iii;
const double eps = 1e-8;
const double pi = 4 * atan(1);
const int inf = 1 << 30;
const int INF = 0x3f3f3f3f;
const int MOD = 1e9 + 7;
int nCase = 0;
//精度正负、0的判断
int dcmp(double x){if (fabs(x) < eps) return 0;return x < 0?-1:1;}
template<class T> inline bool read(T &n){
T x = 0, tmp = 1;
char c = getchar();
while((c < '0' || c > '9') && c != '-' && c != EOF) c = getchar();
if(c == EOF) return false;
if(c == '-') c = getchar(), tmp = -1;
while(c >= '0' && c <= '9') x *= 10, x += (c - '0'),c = getchar();
n = x*tmp;
return true;
}
template <class T> inline void write(T n){
if(n < 0){putchar('-');n = -n;}
int len = 0,data[20];
while(n){data[len++] = n%10;n /= 10;}
if(!len) data[len++] = 0;
while(len--) putchar(data[len]+48);
}
LL QMOD(LL x, LL k) {
LL res = 1LL;
while(k) {if (k & 1) res = res * x % MOD;k >>= 1;x = x * x % MOD;}
return res;
}
const int maxn = 2e5 + 123;
struct Edge {
int v, c, t, nxt;
}e[maxn];
int head[maxn], ecnt;
LL dis[maxn];
bool in[maxn];
int n, m;
inline void addedge(int u,int v,int c,int t) {
e[ecnt] = Edge {v, c, t, head[u]}, head[u] = ecnt++;
// e[ecnt] = Edge {u, c, t, head[v]}, head[v] = ecnt++;
}
void spfa() {
memset(dis, 0x3f, sizeof dis);
memset(in, false,sizeof in);
// cout << dis[0] << endl;
deque<int> que;
que.push_back(0);
dis[0] = 0;
while(!que.empty()) {
int idx = que.front();
que.pop_front();
int u = e[idx].v, c = e[idx].c;
in[idx] = false;
for (int i = head[u];~i;i = e[i].nxt) {
int v = e[i].v;
LL cost = (c == -1 ? 0 : abs(e[i].c - c)) + e[i].t + dis[idx];
if (dis[i] > cost) {
dis[i] = cost;
if (!in[i]) {
in[i] = true;
if (que.empty()) que.push_back(i);
else if (dis[i] < dis[que.front()]) que.push_front(i);
else que.push_back(i);
}
}
}
}
}
int main(int argc, const char * argv[])
{
// freopen("in.txt","r",stdin);
// freopen("out.txt","w",stdout);
// ios::sync_with_stdio(false);
// cout.sync_with_stdio(false);
// cin.sync_with_stdio(false);
while(~scanf("%d%d", &n, &m)) {
memset(head, -1, sizeof head), ecnt = 0;
addedge(1, 1, -1, 0);
Rep(i, 1, m) {
int u, v, c, t;
scanf("%d%d%d%d", &u, &v, &c, &t);
addedge(u, v, c, t);
addedge(v, u, c, t);
}
spfa();
LL ans = 1e18;
// Rep(i, 0, ecnt) {
// printf("[u = %d, dis = %lld]\n", e[i].v, dis[i]);
// }
Rep(i, 0, ecnt) if (e[i].v == n) ans = min(ans, dis[i]);
cout << ans << endl;
}
// showtime;
return 0;
}