csu1808 地铁(最短路)

一个城市中有n个站m条线路(指直接相连接u-v),也就是和城市地铁一样,在某个站换线需要花额外的时间,求1号站到n号站的最短时间消耗。
猛的一看就是普通的最短路问题,但是实际需要改变很多,不能单纯的按照原来的方式求解dis[v]表示到v的最小时间花费。
因为你无法知道这个最小值是由哪条线路过来的,会直接影响后面的换线时间消耗。所以我们纪录走i号线到v的最小时间,
这样就能明白起最小时间和哪条线路了。
dis[i],i线uvdis[i]1vi

/*****************************************
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;
}

猜你喜欢

转载自blog.csdn.net/KIJamesQi/article/details/52447240