[luoguP1266] 速度限制(spfa)

传送门

因为到某一没有限速的路径速度会有不同的可能,所以直接用 dis[i][j] 表示到第 i 个点速度为 j 时的最短时间,然后跑spfa。

——代码

 1 #include <queue>
 2 #include <cstdio>
 3 #include <cstring>
 4
 5 using namespace std;
 6
 7 const int MAXN = 151;
 8 int n, m, d, cnt;
 9 int head[MAXN], to[MAXN * MAXN], next[MAXN * MAXN], spd[MAXN * MAXN], lon[MAXN * MAXN], pr[MAXN][510], ps[MAXN][510];
10 double dis[MAXN][510], ans = 12345678;
11 bool vis[MAXN][510];
12 queue < pair <int, int> > q;
13 pair <int, int> x;
14
15 inline void add(int x, int y, int v, int l)
16 {
17     to[cnt] = y;
18     spd[cnt] = v;
19     lon[cnt] = l;
20     next[cnt] = head[x];
21     head[x] = cnt++;
22 }
23
24 inline void spfa()
25 {
26     int i, j, u, v, s, p;
27     memset(dis, 70, sizeof(dis));
28     q.push(make_pair(0, 70));
29     dis[0][70] = 0;
30     while(!q.empty())
31     {
32         x = q.front();
33         q.pop();
34         u = x.first;
35         s = x.second;
36         vis[u][s] = 0;
37         for(i = head[u]; i != -1; i = next[i])
38         {
39             v = to[i];
40             p = spd[i] == 0 ? s : spd[i];
41             if(dis[v][p] > dis[u][s] + 1.0 * lon[i] / p)
42             {
43                 dis[v][p] = dis[u][s] + 1.0 * lon[i] / p;
44                 pr[v][p] = u;
45                 ps[v][p] = s;
46                 if(!vis[v][p])
47                 {
48                     vis[v][p] = 1;
49                     q.push(make_pair(v, p));
50                 }
51             }
52         }
53     }
54 }
55
56 inline void print(int u, int pos)
57 {
58     if(pr[u][pos] != -1) print(pr[u][pos], ps[u][pos]);
59     printf("%d ", u);
60 }
61
62 int main()
63 {
64     int i, x, y, v, l, pos;
65     scanf("%d %d %d", &n, &m, &d);
66     memset(pr, -1, sizeof(pr));
67     memset(ps, -1, sizeof(ps));
68     memset(head, -1, sizeof(head));
69     for(i = 1; i <= m; i++)
70     {
71         scanf("%d %d %d %d", &x, &y, &v, &l);
72         add(x, y, v, l);
73     }
74     spfa();
75     for(i = 0; i <= 500; i++)
76         if(ans > dis[d][i])
77             ans = dis[d][i], pos = i;
78     print(d, pos);
79     return 0;
80 }

时间: 2024-10-20 20:15:46

[luoguP1266] 速度限制(spfa)的相关文章

P1266 速度限制(分层图spfa)

P1266 速度限制 题目描述 在这个繁忙的社会中,我们往往不再去选择最短的道路,而是选择最快的路线.开车时每条道路的限速成为最关键的问题.不幸的是,有一些限速的标志丢失了,因此你无法得知应该开多快.一种可以辩解的解决方案是,按照原来的速度行驶.你的任务是计算两地间的最快路线. 你将获得一份现代化城市的道路交通信息.为了使问题简化,地图只包括路口和道路.每条道路是有向的,只连接了两条道路,并且最多只有一块限速标志,位于路的起点.两地A和B,最多只有一条道路从A连接到B.你可以假设加速能够在瞬间完

P1266 速度限制

P1266 速度限制 第一次接触这种分层spfa 类似于dp 个人理解 #include<cstdio> #include<iostream> #include<algorithm> #include<queue> using namespace std; struct node { int p; int v; int l; int x; }; struct que { int p; int v; }; queue<que>q; node l[1

UESTC30-最短路-Floyd最短路、spfa+链式前向星建图

最短路 Time Limit: 3000/1000MS (Java/Others) Memory Limit: 65535/65535KB (Java/Others) 在每年的校赛里,所有进入决赛的同学都会获得一件很漂亮的T-shirt.但是每当我们的工作人员把上百件的衣服从商店运回到赛场的时候,却是非常累的!所以现在他们想要寻找最短的从商店到赛场的路线,你可以帮助他们吗? Input 输入包括多组数据. 每组数据第一行是两个整数NN ,MM (N≤100N≤100 ,M≤10000M≤1000

畅通project续HDU杭电1874【dijkstra算法 || SPFA】

http://acm.hdu.edu.cn/showproblem.php?pid=1874 Problem Description 某省自从实行了非常多年的畅通project计划后.最终修建了非常多路.只是路多了也不好,每次要从一个城镇到还有一个城镇时,都有很多种道路方案能够选择,而某些方案要比还有一些方案行走的距离要短非常多.这让行人非常困扰. 如今,已知起点和终点,请你计算出要从起点到终点.最短须要行走多少距离. Input 本题目包括多组数据.请处理到文件结束. 每组数据第一行包括两个正

HDU 2722 Here We Go(relians) Again (spfa)

Here We Go(relians) Again Time Limit : 2000/1000ms (Java/Other)   Memory Limit : 32768/32768K (Java/Other) Total Submission(s) : 1   Accepted Submission(s) : 1 Font: Times New Roman | Verdana | Georgia Font Size: ← → Problem Description The Gorelians

[BZOJ 1295][SCOI2009]最长距离(SPFA+暴力)

题目:http://www.lydsy.com/JudgeOnline/problem.php?id=1295 分析:很巧妙的一道spfa从搜索的角度是搜索在所有1中搜索删除哪T个1,对整个图询问,这样肯定TLE 不妨反过来想一想:对于两个点,弄出联通这两个点所需删除的最少的1,那么就知道这两个点是否可以作为题目要求的起点和终点,如果满足算一下结果和ans比较一下就可以. 所以算法就出来了: 枚举起点(S,T),用SPFA跑出图上的所有点到起点这条路径联通的最少删除的1,那么ans=max(di

poj3268 Silver Cow Party (SPFA求最短路)

其实还是从一个x点出发到所有点的最短路问题.来和回只需分别处理一下逆图和原图,两次SPFA就行了. #include<iostream> #include<cstdio> #include<cstdlib> #include<cstring> #include<string> #include<cmath> #include<map> #include<set> #include<vector> #

POJ--3259--Wormholes【SPFA判负权值回路】

题意:有n个点,之间有m条双向路径,还有w个虫洞,单向,从一点到另一点需要花费时间,但是有虫洞的话会减少时间,一个人想要走某一条路使得他能碰到过去的自己,问这个图是否能让他实现他的想法. 其实就是判一个图是否存在负权值回路,SPFA可以实现,原理是:如果存在负权值回路,那么从源点到某个顶点的距离就可以无限缩短,因此就会无限入队,所以在SPFA中统计每个顶点的入队次数,如果超过了n个(顶点个数)则说明存在负权值回路. 我把输出yes和输出no写反了,WA了两发,看了半天都没发现... #inclu

POJ 3259 Wormholes SPFA算法题解

本题其实也可以使用SPFA算法来求解的,不过就一个关键点,就是当某个顶点入列的次数超过所有顶点的总数的时候,就可以判断是有负环出现了. SPFA原来也是可以处理负环的. 不过SPFA这种处理负环的方法自然比一般的Bellman Ford算法要慢点了. #include <stdio.h> #include <string.h> #include <limits.h> const int MAX_N = 501; const int MAX_M = 2501; const