洛谷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\n",ans);
125     return 0;
126 }

 

posted @ 2018-10-13 23:17  Unstoppable728  阅读(377)  评论(0编辑  收藏  举报