Funny Car Racing UVA - 12661

题意:在一个赛车比赛中,赛道有n(n <= 300)个交叉点和m(m <= 50000)条单向道路。有趣的是:每条路都是周期性关闭的。每条路用5个整数u,v,a,b,t表示(1<=u,v<=n,1<=a,b,t<=1e5),表示起点是u,重点是v,通过时间为t秒。另外这条路会打开a秒,然后关闭b秒,然后再打开a秒,以此类推。当比赛开始时,每条道路刚刚打开。你的赛车必须在道路打开的时候进入该道路,并且在它关闭之前离开(进出道路不花时间,所以可以在打开的瞬间进入,关闭的瞬间离开)。

从s出发,尽早到达目的地t(1<=s,t<=n)。道路的起点和终点不会相同,但可能有两条道路的起点和终点分别相同。

思路:注意点1.每条道路是单向的

2.有可能某条道路的t > a,这条路根本就不能过

#include
#define INF 0x3f3f3f3f
typedef long long ll;
using namespace std;
const int maxn = 300 + 2;
int n,m,st,en;
int d[maxn],done[maxn];
vector g[maxn];
struct node
{
    int v,dd;
    node(int pp,int qq):v(pp),dd(qq){}
    bool operator <(const node & rhs) const
    {
        return dd > rhs.dd;
    }
};
struct edge
{
    int u,v,a,b,t;
    edge(int u1,int v1,int a1,int b1,int t1):u(u1),v(v1),a(a1),b(b1),t(t1){}
};
vector edges;
void init()
{
    edges.clear();
    for(int i = 0;i < maxn;i++) g[i].clear();
}
void addedge(int a1,int b1,int c1,int d1,int e1)
{
    int q;
    edges.push_back(edge(a1,b1,c1,d1,e1));
    q = edges.size();
    g[a1].push_back(q - 1);
}
void dijkstra(int s)
{
    priority_queue Q;
    for(int i = 0;i < maxn;i++) d[i] = INF;
    d[s] = 0; memset(done,0,sizeof(done));
    Q.push(node(s,0));
    while(!Q.empty())
    {
        node x = Q.top(); Q.pop();
        int u = x.v;
        if(done[u]) continue;
        done[u] = true;
        for(int i = 0;i < g[u].size();i++)
        {
            edge & e = edges[g[u][i]];
            int time = INF,res = d[u] % (e.a + e.b);
            if(e.a - res >= e.t) time = e.t;
            else if(e.a >= e.t) time = e.a + e.b - res + e.t;
            if(d[e.v] > d[u] + time)
            {
                d[e.v] = d[u] + time;
                Q.push(node(e.v,d[e.v]));
            }
        }
    }
}
int main()
{
//    freopen("in.txt","r",stdin);
//    freopen("out.txt","w",stdout);
    int kase = 1;
    while(scanf("%d%d%d%d",&n,&m,&st,&en) != EOF)
    {
        init();
        int a1,b1,c1,d1,e1;
        for(int i = 1;i <= m;i++)
        {
            scanf("%d%d%d%d%d",&a1,&b1,&c1,&d1,&e1);
            addedge(a1,b1,c1,d1,e1);
        }
        dijkstra(st);
        printf("Case %d: %d\n",kase++,d[en]);
    }
    return 0;
}

 

你可能感兴趣的:(紫书刷题)