zoukankan      html  css  js  c++  java
  • 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 }
  • 相关阅读:
    2016521-Java-第八周学习总结
    20165221 第七周学习总结
    20165221—JAVA第六周学习心得
    20165221 JAVA第五周学习心得
    20165221 JAVA第四周学习心得
    结对学习创意照
    20165331 第三周学习总结
    20165331 课下作业
    20165331 第二周学习总结
    20165331 第一周学习总结
  • 原文地址:https://www.cnblogs.com/mjtcn/p/9912998.html
Copyright © 2011-2022 走看看