[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 }
View Code

 

转载于:https://www.cnblogs.com/zhenghaotian/p/6816007.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值