zoukankan      html  css  js  c++  java
  • 题解-雅加达的摩天楼 (APIO2015)

    分块思想,机智的建图。

    1.n = min(sqrt(N), 100) ……设一个玄学限制,跑得会快很多。

    2.SPFA 不要加 LLL 也不要加 SLF 优化!千万不要加!不然九十八!

    我写了发 SPFA ,时间略卡。可能 Dijkstra 在这道题会更优秀一些吧……

     1 #include <stdio.h>
     2 #include <deque>
     3 #include <math.h>
     4 
     5 using namespace std;
     6 
     7 const int _V = 30005*105;
     8 const int _E = 30005*500;
     9 const int INF = 1e9;
    10 
    11 deque<int> Q;
    12 int v[_E], w[_E], nxt[_E], fst[_V], dis[_V];
    13 int Tot, N, n, M;
    14 bool mk[_V];
    15 
    16 void Ins(int t1, int t2, int t3)
    17 {
    18     v[++Tot] = t2, w[Tot] = t3;
    19     nxt[Tot] = fst[t1];
    20     fst[t1] = Tot;
    21     return;
    22 }
    23 
    24 void SPFA(int beg)
    25 {
    26     int t = (N-1)*(n+1)+n+1, i;
    27     for (i = 1; i <= t; ++i)
    28         dis[i] = INF, mk[i] = false;
    29     while (!Q.empty()) Q.pop_back();
    30     dis[beg] = 0, mk[beg] = true, Q.push_back(beg);
    31     while (!Q.empty()) {
    32         int p = Q.front();
    33         Q.pop_front(), mk[p] = false;
    34         for (i = fst[p]; i; i = nxt[i]) {
    35             if (dis[v[i]] > w[i]+dis[p]) {
    36                 dis[v[i]] = w[i]+dis[p];
    37                 if (!mk[v[i]]) {
    38                     mk[v[i]] = true;
    39                     Q.push_back(v[i]);
    40                 }
    41                 }
    42             }
    43         }
    44     }
    45     return;
    46 }
    47 
    48 int main()
    49 {
    50     int i, j, k, beg, end;
    51     scanf("%d%d", &N, &M);
    52     n = min((int)sqrt(N+0.5), 100);
    53     for (i = 0; i < N; ++i)
    54         for (j = 1; j <= n; ++j) {
    55             Ins(i*(n+1)+j, i*(n+1)+n+1, 0);
    56             if (i+j < N) {
    57                 Ins(i*(n+1)+j, (i+j)*(n+1)+j, 1);
    58                 Ins((i+j)*(n+1)+j, i*(n+1)+j, 1);
    59             }
    60         }
    61     for (i = 1; i <= M; ++i) {
    62         int pos, p;
    63         scanf("%d%d", &pos, &p);
    64         if (i == 1) beg = pos;
    65         else if (i == 2) end = pos;
    66         if (p <= n) {
    67             Ins(pos*(n+1)+n+1, pos*(n+1)+p, 0);
    68         } else {
    69             for (j = pos+p; j < N; j += p)
    70                 Ins(pos*(n+1)+n+1, j*(n+1)+n+1, (j-pos)/p);
    71             for (j = pos-p; j >= 0; j -= p)
    72                 Ins(pos*(n+1)+n+1, j*(n+1)+n+1, (pos-j)/p);
    73         }
    74     }
    75     SPFA(beg*(n+1)+n+1);
    76     printf("%d
    ", dis[end*(n+1)+n+1] >= INF ? -1 : dis[end*(n+1)+n+1]);
    77     return 0;
    78 }
    View Code
  • 相关阅读:
    HDU 1950 Bridging signals
    HDU 1025 (LIS+二分) Constructing Roads In JGShining's Kingdom
    HDU 1160 FatMouse's Speed
    HDU 1257 最少拦截系统
    HDU 1574 RP问题
    解同余式ax ≡ c(mod m)
    拓展欧几里得算法及代码实现
    百练 1088 滑雪
    [再做01背包] POJ 3624 Charm Bracelet
    百练 2755 神奇的口袋
  • 原文地址:https://www.cnblogs.com/ghcred/p/9294562.html
Copyright © 2011-2022 走看看