Description
Bobo 居住在大城市 ICPCCamp。
ICPCCamp 有 n 个地铁站,用 1,2,…,n 编号。 m 段双向的地铁线路连接 n 个地铁站,其中第 i 段地铁属于 c
i 号线,位于站 a
i,b
i 之间,往返均需要花费 t
i 分钟(即从 a
i 到 b
i 需要 t
i 分钟,从 b
i 到 a
i 也需要 t
i分钟)。
众所周知,换乘线路很麻烦。如果乘坐第 i 段地铁来到地铁站 s,又乘坐第 j 段地铁离开地铁站 s,那么需要额外花费 |c
i-c
j | 分钟。注意,换乘只能在地铁站内进行。
Bobo 想知道从地铁站 1 到地铁站 n 所需要花费的最小时间。
Input
输入包含不超过 20 组数据。
每组数据的第一行包含两个整数 n,m (2≤n≤10
5,1≤m≤10
5).
接下来 m 行的第 i 行包含四个整数 a
i,b
i,c
i,t
i (1≤a
i,b
i,c
i≤n,1≤t
i≤10
9).
保证存在从地铁站 1 到 n 的地铁线路(不一定直达)。
Output
对于每组数据,输出一个整数表示要求的值。
Sample Input
3 3
1 2 1 1
2 3 2 1
1 3 1 1
3 3
1 2 1 1
2 3 2 1
1 3 1 10
3 2
1 2 1 1
2 3 1 1
Sample Output
1 32
拆点最短路,把每个点分为从小到大不同的站点,之间用边相连,然后跑最短路即可。
#include<set> #include<map> #include<ctime> #include<cmath> #include<stack> #include<queue> #include<bitset> #include<cstdio> #include<string> #include<cstring> #include<iostream> #include<algorithm> #include<functional> #define rep(i,j,k) for (int i = j; i <= k; i++) #define per(i,j,k) for (int i = j; i >= k; i--) #define loop(i,j,k) for (int i = j;i != -1; i = k[i]) #define lson x << 1, l, mid #define rson x << 1 | 1, mid + 1, r #define ff first #define ss second #define mp(i,j) make_pair(i,j) #define pb push_back #define pii pair<int,LL> #define in(x) scanf("%d", &x); using namespace std; typedef long long LL; const int low(int x) { return x&-x; } const double eps = 1e-9; const int INF = 0x7FFFFFFF; const int mod = 1e9 + 7; const int N = 6e5 + 10; struct point { int x, y, c, v, q; void read() { scanf("%d%d%d%d", &x, &y, &c, &v); q = 0; if (x > y) swap(x, y); } bool operator<(const point &a)const { return c > a.c; } }g[N]; int n, m, l, r, tot; int ft[N], nt[N], u[N], v[N], sz; int Ft[N], Nt[N], U[N], Sz; struct poi { LL x, y; poi(LL x, LL y) :x(x), y(y) {} bool operator<(const poi &a)const { return y > a.y; } }; LL dis[N]; void add(int x, int y, int z) { u[sz] = y; v[sz] = z; nt[sz] = ft[x]; ft[x] = sz++; u[sz] = x; v[sz] = z; nt[sz] = ft[y]; ft[y] = sz++; } int main() { while (scanf("%d%d", &n, &m) != EOF) { tot = sz = Sz = 0; rep(i, 1, n) Ft[i] = -1; rep(i, 1, m) g[i].read(); sort(g + 1, g + m + 1); rep(i, 1, m) { U[Sz] = i; Nt[Sz] = Ft[g[i].x]; Ft[g[i].x] = Sz++; U[Sz] = i; Nt[Sz] = Ft[g[i].y]; Ft[g[i].y] = Sz++; } rep(i, 1, n) { if (i == n) r = tot; int col = 0, bef = 0; loop(j, Ft[i], Nt) { point &q = g[U[j]]; if (q.c != col) { ft[++tot] = -1; if (col) add(bef, tot, q.c - col); bef = tot; col = q.c; } if (q.x < i) add(bef, q.q, q.v); else q.q = bef; } if (i == 1) l = tot; } LL ans = -1; rep(i, l + 1, tot) dis[i] = -1; priority_queue<poi> p; rep(i, 1, l) p.push(poi(i, dis[i] = 0)); while (!p.empty()) { poi q = p.top(); p.pop(); loop(i, ft[q.x], nt) { if (dis[u[i]] == -1 || dis[u[i]] > q.y + v[i]) { p.push(poi(u[i], dis[u[i]] = q.y + v[i])); } } } per(i, tot, r + 1) ans = ans == -1 ? dis[i] : min(ans, dis[i]); printf("%lld\n", ans); } return 0; }