• poj 3539 Elevator——同余类bfs


    题目: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;
    }
  • 相关阅读:
    ngalain 自带的g2图表在无法使用的外网情况下不能加载图表
    Angular+Ionic Token有效期内打开APP不用经过登录页
    ActiveMQ
    C# 忽略某些字段的反序列化
    安装 nvm后ng不是内部或外部命令,也不是可运行的程序
    Angular使用rxjs实现发布订阅
    The user specified as a definer ('root'@'%') does not exist
    别在高并发场景中使用悲观锁
    Nacos 实现原理详解
    过滤器Filter和拦截器HandlerInterceptor
  • 原文地址:https://www.cnblogs.com/Narh/p/9275440.html
Copyright © 2020-2023  润新知