码迷,mamicode.com
首页 > 其他好文 > 详细

poj 3539 Elevator——同余类bfs

时间:2018-07-06 21:36:47      阅读:448      评论:0      收藏:0      [点我收藏+]

标签:ext   return   src   const   printf   using   pen   include   pop   

题目:http://poj.org/problem?id=3539

考虑把层数分为模a剩余系。同类内可通过+若干个a走到。

不同类之间需要通过+b、+c来走到。

需要求出每一类中最小的能走到的。即最短路。

注意memset成0x3f!不要直接memset成1!

  仔细一看,long long下赋1是17位,赋0x3f是19位。而h是18位。

技术分享图片
#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
#define ll long long
using namespace std;
const int N=1e5+5;
ll h,dis[N],ans;
int a,b,c,head[N],xnt;
bool vis[N];
struct Ed{
  int next,to,w;
  Ed(int n=0,int t=0,int z=0):next(n),to(t),w(z) {}
}ed[N<<1];
void dj()
{
  memset(dis,0x3f,sizeof dis);dis[1%a]=1;//%a //0x3f
  priority_queue<pair<ll,int> > q;
  q.push(make_pair(-1,1%a));
  while(q.size())
    {
      int k=q.top().second;q.pop();
      while(q.size()&&vis[k])k=q.top().second,q.pop();
      if(vis[k])break;vis[k]=1;
      for(int i=head[k],v;i;i=ed[i].next)
    if(dis[k]+ed[i].w<dis[v=ed[i].to])
      {
        dis[v]=dis[k]+ed[i].w;q.push(make_pair(-dis[v],v));
      }
    }
}
int main()
{
  scanf("%lld%d%d%d",&h,&a,&b,&c);
  for(int i=0;i<a;i++)
    {
      ed[++xnt]=Ed(head[i],(i+b)%a,b);head[i]=xnt;
      ed[++xnt]=Ed(head[i],(i+c)%a,c);head[i]=xnt;
    }
  dj();
  for(int i=0;i<a;i++)if(dis[i]<=h)ans+=(h-dis[i])/a+1;//<=h
  printf("%lld",ans);
  return 0;
}
dj

再来个跑得快的(spfa)。

#include<iostream>
#include<cstdio>
#include<cstring>
#define ll long long
using namespace std;
const int N=1e5+5;
ll ans,h,dis[N];
int a,b,c,q[N<<4],hd,tl;
bool vis[N];
int main()
{
  scanf("%lld%d%d%d",&h,&a,&b,&c);
  if(a<b)swap(a,b);if(a<c)swap(a,c);
  memset(dis,0x3f,sizeof dis);dis[1%a]=1;
  hd=1;q[++tl]=1;vis[1%a]=1;
  while(hd<=tl)
    {
      int k=q[hd++];vis[k]=0;
      if(dis[(k+b)%a]>dis[k]+b)
    {
      dis[(k+b)%a]=dis[k]+b;
      if(!vis[(k+b)%a])q[++tl]=(k+b)%a,vis[(k+b)%a]=1;
    }
      if(dis[(k+c)%a]>dis[k]+c)
    {
      dis[(k+c)%a]=dis[k]+c;
      if(!vis[(k+c)%a])q[++tl]=(k+c)%a,vis[(k+c)%a]=1;
    }
    }
  for(int i=0;i<a;i++)if(dis[i]<=h)ans+=(h-dis[i])/a+1;
  printf("%lld",ans);
  return 0;
}

 

poj 3539 Elevator——同余类bfs

标签:ext   return   src   const   printf   using   pen   include   pop   

原文地址:https://www.cnblogs.com/Narh/p/9275440.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!