CF 96 D. Volleyball

D. Volleyball

http://codeforces.com/contest/96/problem/D

题意:

  n个路口,m条双向路,每条长度为w。每个路口有一个出租车司机,最多可以乘坐这辆车走长度只要坐他的车,就必须交c元,最多可以载你走的长度为t的路。问从x到y的最小花费是多少。

分析:

  第一遍SPFA求出每个点它能到的所有点,边权就是乘坐出租车的费用,第二遍直接跑最短路。稀疏图用了spfa

代码:

 1 #include<cstdio>
 2 #include<algorithm>
 3 #include<cstring>
 4 #include<cmath>
 5 #include<iostream>
 6 #include<cctype>
 7 #include<set>
 8 #include<vector>
 9 #include<queue>
10 #include<map>
11 #define fi(s) freopen(s,"r",stdin);
12 #define fo(s) freopen(s,"w",stdout);
13 using namespace std;
14 typedef long long LL;
15 
16 inline int read() {
17     int x=0,f=1;char ch=getchar();for(;!isdigit(ch);ch=getchar())if(ch=='-')f=-1;
18     for(;isdigit(ch);ch=getchar())x=x*10+ch-'0';return x*f;
19 }
20 
21 const int N = 1005;
22 
23 struct ShortestPath{
24     int head[N], len[N * N], nxt[N * N], to[N * N], q[N * N], En;
25     LL dis[N], INF;
26     bool vis[N];
27     void add_edge(int u,int v,int w) {
28         ++En; to[En] = v; len[En] = w; nxt[En] = head[u]; head[u] = En;
29     }
30     void spfa(int S) {
31         memset(dis, 0x3f, sizeof(dis)); INF = dis[0]; 
32         int L = 1, R = 0; 
33         dis[S] = 0; q[++R] = S; vis[S] = true;
34         while (L <= R) {
35             int u = q[L ++]; vis[u] = false;
36             for (int i = head[u]; i; i = nxt[i]) {
37                 int v = to[i];
38                 if (dis[v] > dis[u] + len[i]) {
39                     dis[v] = dis[u] + len[i];
40                     if (!vis[v]) q[++R] = v, vis[v] = true;
41                 }
42             }
43         }
44     }    
45 }G1, G2;
46 
47 int main() {
48     int n = read(), m = read(), S = read(), T = read();
49     for (int i = 1; i <= m; ++i) {
50         int u = read(), v = read(), w = read();
51         G1.add_edge(u, v, w); G1.add_edge(v, u, w);
52     }
53     for (int i = 1; i <= n; ++i) {
54         int d = read(), c = read();
55         G1.spfa(i);
56         for (int j = 1; j <= n; ++j) {
57             if (G1.dis[j] <= d && i != j) G2.add_edge(i, j, c); // 此处为单向边 
58         }
59     }
60     G2.spfa(S);
61     if (G2.dis[T] == G2.INF) puts("-1");
62     else cout << G2.dis[T];
63     return 0;
64 }

 

posted @ 2018-11-07 20:08  MJT12044  阅读(275)  评论(0编辑  收藏  举报