例题11-11 有趣的赛车比赛(Funny Car Racing, UVa 12661)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/richenyunqi/article/details/89640019

欢迎访问我的Uva题解目录哦 https://blog.csdn.net/richenyunqi/article/details/81149109

题目描述

例题11-11 有趣的赛车比赛(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 105 (1≤u,v≤n,1≤a,b,t≤105), 表示起点是u,终点是v,通过时间为t秒。另外,这条路会打开a秒,然后关闭b秒,然后再打开a秒,依此类推。当比赛开始时,每条道路刚刚打开。你的赛车必须在道路打开的时候进入该道路,并且在它关闭之前离开(进出道路不花时间,所以可以在打开的瞬间进入,关闭的瞬间离开)。
你的任务是从s出发,尽早到达目的地t 1 s , t n (1≤s,t≤n) 。道路的起点和终点不会相同,但是可能有两条道路的起点和终点分别相同。

算法设计

使用Dijkstra算法,注意在计算一个结点u出发的边权时要考虑等待时间即可。

C++代码

#include<bits/stdc++.h>
using namespace std;
struct Edge{
    int from,to,cost,open,close;
    Edge(int f,int t,int o,int clo,int c):from(f),to(t),open(o),close(clo),cost(c){}
};
const int MAXV=305;
vector<Edge>edges;
vector<int>graph[MAXV];
int n,m,s,t,dis[MAXV];
int arriveNext(int arrive,const Edge&e){//计算从到达道路e起点的时间arrive到达道路e终点时间
    int temp=arrive%(e.open+e.close);
    if(temp+e.cost<=e.open)
        return arrive+e.cost;
    return arrive+e.open+e.close-temp+e.cost;
}
void Dijkstra(){
    using pii=pair<int,int>;
    priority_queue<pii,vector<pii>,greater<pii>>pq;//pii的first成员存储dis,second成员存储结点编号
    fill(dis,dis+MAXV,INT_MAX);
    dis[s]=0;
    pq.push({0,s});
    while(!pq.empty()){
        pii p=pq.top();
        pq.pop();
        if(dis[p.second]!=p.first)
            continue;
        for(int i:graph[p.second]){
            Edge&e=edges[i];
            int arrive=arriveNext(dis[p.second],e);//到达道路e终点的时间
            if(dis[e.to]>arrive){
                dis[e.to]=arrive;
                pq.push({dis[e.to],e.to});
            }
        }
    }
}
int main(){
    for(int ii=1;~scanf("%d%d%d%d",&n,&m,&s,&t);++ii){
        edges.clear();
        fill(graph,graph+n+1,vector<int>());
        while(m--){
            int u,v,a,b,t;
            scanf("%d%d%d%d%d",&u,&v,&a,&b,&t);
            if(t>a)//如果通过该路的用时比该路的开放时间还要长,直接忽略该路
                continue;
            graph[u].push_back(edges.size());
            edges.push_back(Edge(u,v,a,b,t));
        }
        Dijkstra();
        printf("Case %d: %d\n",ii,dis[t]);
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/richenyunqi/article/details/89640019
car
今日推荐