UVA 12661 Funny Car Racing

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. It’s always possible to arrive at t from s.
Sample Input
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
Sample Output
Case 1: 20
Case 2: 9

// 就....
// 噼里啪啦 噼里啪啦 简简单单最短路
#include <cstring>
#include <cstdio>
#include <iostream>
#include <queue>
#define Maxn 305
using namespace std;
bool vis[Maxn];
int head[Maxn],tot,dis[Maxn];

struct Node {// Dijkstra的状态节点
    int v,dis;
    bool operator < (const Node &that) const {
        return dis > that.dis;
    }
};
struct Edge{
    int v,next,open,close,t;
}e[50005];
inline void Add_Edge(int u,int v,int a,int b,int t) {
    e[++tot].v = v,e[tot].open = a,e[tot].close = b;
    e[tot].t = t; e[tot].next = head[u]; head[u] = tot;
}

int Dijkstra(int S,int T) {
    memset(dis,0x7f,sizeof(dis));
    memset(vis,0,sizeof(vis));
    priority_queue<Node> q;
    dis[S] = 0;
    q.push((Node){S,0});
    while(!q.empty()) {
        Node x = q.top(); q.pop();
        int u = x.v;
        if(u == T) return x.dis;
        vis[u] = true;
        for(int i=head[u]; i; i=e[i].next) {
            int v = e[i].v;
            int progress = dis[u] % (e[i].close + e[i].open);
            if(progress + e[i].t <= e[i].open) {// 可以直接通过
                if(dis[v] > dis[u] + e[i].t) {
                    dis[v] = dis[u] + e[i].t;
                    q.push((Node){v,dis[v]});
                }
            }
            else { // 当前剩余的时间不够通过   需要等待一定时间
                int waiting = e[i].open + e[i].close - progress;
                if(dis[v] > waiting + dis[u] + e[i].t) {
                    dis[v] = waiting + dis[u] + e[i].t;
                    q.push((Node){v,dis[v]});
                }
            }
        }
    }
    return dis[T];
}

int main(int argc,char* argv[]) {
    int n,m,kase = 0,S,T;
    while(scanf("%d %d %d %d",&n,&m,&S,&T) != EOF) {
        tot = 0;
        memset(head,0,sizeof(head));
        for(int u,v,a,b,c,i=1; i<=m; i++) {
            scanf("%d %d %d %d %d",&u,&v,&a,&b,&c);
            if(c <= a) Add_Edge(u,v,a,b,c);
        }
        printf("Case %d: %d\n",++kase,Dijkstra(S,T));
    }
    //system("pause");
    return 0;
}
上一篇:UVa 11478 - Halum (差分约束)


下一篇:UVa 12219 Common Subexpression Elimination (杂)