zoukankan      html  css  js  c++  java
  • Funny Car Racing

    Description

    There is a funny car racing in a city with n
    junctions and m directed roads.

    The funny part is: each road is open and closed periodically. Each road is associate with two integers (a,b), that means the road will be open for a seconds, then closed for b seconds, then open for a seconds… All these start from the beginning of the race. You must enter a road when it’s open, and leave it before it’s closed again.

    Your goal is to drive from junction s and arrive at junction t as early as possible. Note that you can wait at a junction even if all its adjacent roads are closed.

    Input

    There will be at most 30 test cases. The first line of each case contains four integers n,m,s,t
    (1≤n≤300, 1≤m≤50,000, 1≤s,t≤n). Each of the next m lines contains five integers u,v,a,b,t (1≤u,v≤n, 1≤a,b,t≤105), that means there is a road starting from junction u ending with junction v. It’s open for a seconds, then closed for b seconds (and so on). The time needed to pass this road, by your car, is t. No road connects the same junction, but a pair of junctions could be connected by more than one road.

    Output

    For each test case, print the shortest time, in seconds. If it’s not possible to arrive at t from s (maybe your car is too slow!), print -1.

    Samples

    Input Copy

    3 2 1 3
    1 2 5 6 3
    2 3 7 7 6
    3 2 1 3
    1 2 5 6 3
    2 3 9 5 6
    

    Output

    Case 1: 20
    Case 2: 9
    

    题意:
    n个路口,m条街道,每条街道都是有向的
    并且这m条街道open a秒 close b秒(循环往复),自己的车通过这条道路需要t秒
    可以从路口等待某一条道路open,必须在道路close 之前通过,且必须在另一条道路open的时候进入
    问能否从s点到达t点,如果不能,输出-1,如果能输出最短的时间

    细节的地方加在了代码里,在建图的过程中,如果说a > t,那么说这条路无论如何是走不过去的,所以干脆直接不建边

    priority_queue<int, vector<int>, greater<int>> xiaogen;
    priority_queue<int, vector<int>, less<int>> dagen;
    const ll inf = 9223372036854775807;
    const ll INF = 0x3f3f3f3f;
    const int maxn = 3e5 + 7;
    const int mod = 1000000007;
    #define PI (double)acos(-1.0)
    #define debug(x) cout << #x << "  ->  " << x << endl
    #define IOS                      
        ios::sync_with_stdio(false); 
        cin.tie(NULL);               
        cout.tie(NULL);
    #define lowbit(x) (x & (-x))
    #define Clear(x, val) memset(x, val, sizeof x)
    typedef pair<int, int> PII;
    int cnt, head[maxn], n, m, s, t;
    int dis[maxn], vis[maxn];
    struct node {
        int u, v, a, b, t;
        int nex;
    } e[maxn];
    void add(int u, int v, int a, int b, int t) {
        e[cnt].u = u, e[cnt].v = v;
        e[cnt].a = a, e[cnt].b = b, e[cnt].t = t;
        e[cnt].nex = head[u];
        head[u] = cnt++;
    }
    void dij() {
        priority_queue<PII> que;
        Clear(dis, 0x3f3f3f3f);
        Clear(vis, false);
        dis[s] = 0;
        que.push({0, s});
        vis[s] = true;
        while (que.size()) {
            PII tp = que.top();
            que.pop();
            int u = tp.second;
            vis[u] = false; /// not in the queue
            for (int i = head[u]; ~i; i = e[i].nex) {
                int v = e[i].v;
                /**
                t1代表到达该点时,道路已经开放多长时间,如果已经开放的时间 + 通过需要的时间 <= 该周期总共开放的时间
                说明是可以通过的
                否则就需要等待该门重新开放,总共时间 = 等待时间 + 通过时间
                在该周期需要等待的时间 = a + b - t1
                通过需要的时间即为t
                所以总时间为 a + b - t1 + t
                **/
                int t1 = dis[u] % (e[i].a + e[i].b), t2;
                if (t1 + e[i].t <= e[i].a)
                    t2 = e[i].t;
                else
                    t2 = e[i].a + e[i].b + e[i].t - t1;
                if (dis[v] > dis[u] + t2) {
                    dis[v] = dis[u] + t2;
                    if (!vis[v])
                        que.push({dis[v], v});
                }
            }
        }
    }
    int main() {
    	int _ = 0;
        while (cin >> n >> m >> s >> t) {
            Clear(head, -1);
            cnt = 0;
            for (int i = 1; i <= m; i++) {
                int u = read, v = read, a = read, b = read, t = read;
                if (a < t)
                    continue;
                add(u, v, a, b, t);
            }
            dij();
            printf("Case %d: %d
    ", ++_, dis[t] == 0x3f3f3f3f ? -1 : dis[t]);
        }
        return 0;
    }
    /**
    
    
    **/
    
  • 相关阅读:
    SQL 创建存储过程,让主键自增
    C# 实例练习(第二天)
    IT科技企业逻辑思维面试题
    C#学习——简介(第一天)
    C#中 ??、 ?、 ?: 、?.、?[ ]
    SQL Server类型与C#类型对应关系
    ios 键盘折叠
    html 水印效果
    JQuery筛选器全系列介绍
    将时间改为显示:几天前,几小时前,或者几分钟前
  • 原文地址:https://www.cnblogs.com/PushyTao/p/15459808.html
Copyright © 2011-2022 走看看