zoukankan      html  css  js  c++  java
  • 洛谷P3403跳楼机(最短路构造/同余最短路)

    题目->

    解题思路:

    最短路构造很神啊。

    先用前两个值跑在第三个值模意义下的同余最短路(这步贪心可以证明,如果第三步长为z,那么如果n+z可以达到,n+2z同样可以达到)

    最后计算与楼顶差多少个模计算一下就好了(细节:不要忘了自己也是一个解)。

    代码:

      1 #include<queue>
      2 #include<cstdio>
      3 #include<cstring>
      4 #include<algorithm>
      5 typedef long long lnt;
      6 struct pnt{
      7     int hd;
      8     lnt dis;
      9     int no;
     10     bool vis;
     11     bool friend operator < (pnt x,pnt y)
     12     {
     13         return x.dis>y.dis;
     14     }
     15 }p[1000000];
     16 /*class heap{
     17     public:
     18         void push(pnt x)
     19         {
     20             ln[++siz]=x;
     21             int nw=siz;
     22             while((nw>>1)>=1)
     23             {
     24                 int nx=nw>>1;
     25                 if(ln[nx].dis<=ln[nw].dis)
     26                         break;
     27                 std::swap(ln[nx],ln[nw]);
     28                 nw=nx;
     29             }
     30             return ;
     31         }
     32         void pop(void)
     33         {
     34             ln[1]=ln[siz--];
     35             int nw=1;
     36             while((nw<<1)<=siz)
     37             {
     38                 int nx=nw<<1;
     39                 if(ln[nx+1].dis<ln[nx].dis&&nx<siz)
     40                     nx++;
     41                 if(ln[nx].dis>=ln[nw].dis)
     42                         break;
     43                 std::swap(ln[nx],ln[nw]);
     44                 nw=nx;
     45             }
     46             return ;
     47         }
     48         int top(void)
     49         {
     50             return ln[1].no;
     51         }
     52         bool empty(void)
     53         {
     54             return (siz==0);
     55         }
     56     private:
     57         pnt ln[1000000];
     58         int siz;
     59 }Q;*/
     60 std::priority_queue<pnt>Q;
     61 struct ent{
     62     int twd;
     63     int lst;
     64     lnt vls;
     65 }e[1000000];
     66 lnt H;
     67 int x,y,z;
     68 int cnt;
     69 lnt ans;
     70 void ade(int f,int t,lnt v)
     71 {
     72     cnt++;
     73     e[cnt].twd=t;
     74     e[cnt].lst=p[f].hd;
     75     e[cnt].vls=v;
     76     p[f].hd=cnt;
     77     return ;
     78 }
     79 void Init(void)
     80 {
     81     for(int i=0;i<=z;i++)
     82     {
     83         p[i].no=i;
     84         p[i].dis=0x3f3f3f3f3f3f3f3fll;
     85     }
     86     p[1%z].dis=1;
     87     return ;
     88 }
     89 void Dij(void)
     90 {
     91     Q.push(p[1%z]);
     92     while(!Q.empty())
     93     {
     94         int x=Q.top().no;
     95         Q.pop();
     96         if(p[x].vis)
     97             continue;
     98         p[x].vis=true;
     99         for(int i=p[x].hd;i;i=e[i].lst)
    100         {
    101             int to=e[i].twd;
    102             if(p[to].dis>p[x].dis+e[i].vls)
    103             {
    104                 p[to].dis=p[x].dis+e[i].vls;
    105                 Q.push(p[to]);
    106             }
    107         }
    108     }
    109     return ;
    110 }
    111 int main()
    112 {
    113     scanf("%lld%d%d%d",&H,&x,&y,&z);
    114     Init();
    115     for(int i=0;i<z;i++)
    116     {
    117         ade(i,(i+x)%z,x);
    118         ade(i,(i+y)%z,y);
    119     }
    120     Dij();
    121     for(int i=0;i<z;i++)
    122         if(p[i].dis<=H)
    123             ans+=((H-p[i].dis)/z+1);
    124     printf("%lld
    ",ans);
    125     return 0;
    126 }
  • 相关阅读:
    《信息学奥赛一本通》提高版题解索引
    QUERY [ 单调栈 ]
    [ 模拟退火 ] bzoj3860 平衡点
    [ 考试 ] 7.12
    离线和简单分治
    [ 校内OJ ] NOIP2019模拟赛(九)
    校内模拟考 (一)
    Codeforces 808E
    学习笔记—点分治
    [ 线段树+哈希 ] 反等差数列
  • 原文地址:https://www.cnblogs.com/blog-Dr-J/p/9784722.html
Copyright © 2011-2022 走看看