最短路 uva12661 Funny Car Racing

传送门:点击打开链接

题意:给你有向图,每条边呈周期性开放,即开放a时间,再关闭b时间。再开放a时间以此类推

假设时间不足以穿过这条路则不能走。你能够在节点等待时间,问从s走到t所须要的最小时间

细致想一想这题。对于某条边。越早走到u点一定是最优的,大不了我就等时间嘛

所以,这仅仅是一个普通的dijistra然后略微在每一条边的距离上做了点手脚而已

在节点等待时间。我们能够觉得是某一条路的长度添加了,所以仅仅要在读取边长度的时候,略微处理一下等待时间。就能够了

须要注意的地方:

1.假设开放时间小于边的长度,这条边是不管如何都不能通过的。所以一開始就不能把这条边加入进去

2.假设到达某一点时,这条边是开放的。可是剩下的开放时间已经不足以通过这条边,那么要等到关闭后。又一次开放时。才干通过

#include<map>
#include<set>
#include<cmath>
#include<stack>
#include<queue>
#include<cstdio>
#include<string>
#include<vector>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<functional>
#define FIN freopen("input.txt","r",stdin)
#define FOUT freopen("output.txt","w+",stdout)

using namespace std;
typedef long long LL;
typedef pair<int, int> PII;
typedef pair<LL, int> PLI;

const int MX = 1e5 + 5;
const int INF = 0x3f3f3f3f;

int Head[MX], Next[MX], rear;

struct Edge {
    int u, v, cost, a, b;
} E[MX];

void edge_init() {
    rear = 0;
    memset(Head, -1, sizeof(Head));
}

void edge_add(int u, int v, int cost, int a, int b) {
    E[rear].u = u;
    E[rear].v = v;
    E[rear].cost = cost;
    E[rear].a = a;
    E[rear].b = b;
    Next[rear] = Head[u];
    Head[u] = rear++;
}

LL d[MX];
void dijistra(int Begin) {
    memset(d, INF, sizeof(d));
    d[Begin] = 0;

    priority_queue<PLI, vector<PLI>, greater<PLI> >work;
    work.push(PLI(0, Begin));

    while(!work.empty()) {
        PLI f = work.top();
        work.pop();

        LL dist = f.first;
        int u = f.second;

        for(int id = Head[u]; ~id; id = Next[id]) {
            int tq = E[id].a + E[id].b, time = dist % tq, add = 0;
            if(time > E[id].a || time + E[id].cost > E[id].a) add = tq - time;

            int cost = E[id].cost + add, v = E[id].v;
            if(dist + cost < d[v]) {
                d[v] = dist + cost;
                work.push(PLI(dist + cost, v));
            }
        }
    }
}

int main() {
    int n, m, s, t, ansk = 0; //FIN;
    while(~scanf("%d%d%d%d", &n, &m, &s, &t)) {
        edge_init();
        for(int i = 1; i <= m; i++) {
            int u, v, a, b, cost;
            scanf("%d%d%d%d%d", &u, &v, &a, &b, &cost);
            if(a >= cost) edge_add(u, v, cost, a, b);
        }
        dijistra(s);

        printf("Case %d: %lld\n", ++ansk, d[t]);
    }
    return 0;
}
时间: 2024-11-17 21:53:14

最短路 uva12661 Funny Car Racing的相关文章

UVa12661 Funny Car Racing (最短路)

链接:http://vjudge.net/problem/UVA-12661 分析:带权图最短路.仍然调用标准的Dijkstra算法,只是在松弛操作时需要分情况讨论. 1 #include <cstdio> 2 #include <cstring> 3 #include <vector> 4 #include <queue> 5 using namespace std; 6 7 const int maxn = 300 + 5; 8 9 struct Edg

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

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 twointegers (a; b), that means the road will be open for a seconds, then closed for

CSU 1333 Funny Car Racing (最短路)

题目链接: http://acm.csu.edu.cn/OnlineJudge/problem.php?id=1333 解题报告:一个图里面有n个点和m条单向边,注意是单向边,然后每条路开a秒关闭b秒,问从s点到t点的最短时间.一个简单的最短路稍微变了一下. 卡了很久就因为没看到边是单向边,无语.可以用队列优化. 1 #include<cstdio> 2 #include<cstring> 3 #include<iostream> 4 #include<algor

UVA 12661 Funny Car Racing 有趣的赛车比赛(单源最短路,SSSP,变形)

题意:赛道有n个交叉点,和m条单向路径(有重边),每条路都是周期性关闭的,且通过仍需一段时间.在比赛开始时,所有道路刚好打开,选择进入该道路必须满足“在打开的时间段进入,在关闭之前出来”,即不可在路上逗留,但是可以在交叉点逗留.问到达终点的时间要多少? 思路:最短路,而且正权,用Dijkstra+优先队列够了.主要的难点在计算是否可以进入该路段,画图清晰点. 1 #include <bits/stdc++.h> 2 #define LL long long 3 #define pii pair

CSU 1333: Funny Car Racing 最短路

题目连接:http://acm.csu.edu.cn/OnlineJudge/problem.php?id=1333 题意:给你一个n个顶点,m条边(每条边都有三个参数,开放时间,关闭时间,和通过这条边的时间)的有向图: 要你求从s 到 t 的最短路:dijkstra算法可解: 坑点:我用的是队列优化+Vector存储每条边: 在每次调用dijkstra后,必须初始化邻接表,在这个地方坑了好久,这是第二次了,以后记住 如果用vector就要初始化~ 附上代码: #include <iostrea

UVa 12661 (单源最短路) Funny Car Racing

题意: 有一个赛车跑道,可以看做一个加权有向图.每个跑道(有向边)还有一个特点就是,会周期性地打开a秒,然后关闭b秒.只有在赛车进入一直到出来,该跑道一直处于打开状态,赛车才能通过. 开始时所有跑道处于刚打开的状态,求从起点到终点的最短时间. 分析: 设d[i]为起点到节点i的最短时间. 和普通的单源最短路问题一样,只不过在进行松弛操作的时候分两种情况.松弛的前提是,赛道打开的时间不短于赛车通过的时间. 赛车从进入直到出跑道,一直是打开状态.则d[v] = min(d[v], d[u] + t)

H - 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 fo

hdu3461Marriage Match IV 最短路+最大流

//给一个图.给定起点和终点,仅仅能走图上的最短路 //问最多有多少种走的方法.每条路仅仅能走一次 //仅仅要将在最短路上的全部边的权值改为1.求一个最大流即可 #include<cstdio> #include<cstring> #include<iostream> #include<queue> #include<vector> using namespace std ; const int inf = 0x3f3f3f3f ; const