【洛谷3043】跳楼机

题面

https://www.luogu.org/problem/P3403

题解

// luogu-judger-enable-o2
#include<cstdio>
#include<iostream>
#include<cstring>
#include<vector>
#include<queue>
#define ri register unsigned long long 
#define N 100500
#define LL unsigned long long
using namespace std;

vector<LL> to[N],len[N];
LL dis[N]; bool vis[N];
LL x,y,z;
LL h;

struct node {
  LL x; LL d;
  bool operator < (const node &rhs) const {
    return d>rhs.d;
  }
};
priority_queue<node> q;

void add_edge(LL x,LL y,LL z) {
  to[x].push_back(y);len[x].push_back(z);
}

void dij(){
  for (ri i=0;i<x;i++) dis[i]=h+1;
  dis[1]=1;
  q.push((node){1,1});
  while (!q.empty()) {
    int x=q.top().x; q.pop();
    if (vis[x]) continue;
    vis[x]=1;
    for (ri i=0;i<to[x].size();i++) if (dis[to[x][i]]>dis[x]+len[x][i]) {
      dis[to[x][i]]=dis[x]+len[x][i];
      q.push((node){to[x][i],dis[to[x][i]]});
    }
  }
}

LL count(LL h,LL i) {
  if (h<i) return 0LL;
  if (i==0) return h/x; else return (h-i)/x+1;
}

int main(){
  scanf("%llu",&h);
  scanf("%llu%llu%llu",&x,&y,&z);
  if (x==1 || y==1 || z==1) {
    cout<<h<<endl;
    return 0;
  }
  for (ri i=0;i<x;i++) {
    add_edge(i,(i+y)%x,y);
    add_edge(i,(i+z)%x,z);
  }
  dij();
  LL ans=0;
  for (ri i=0;i<x;i++) {
    ans+=count(h,i)-count(dis[i]-1,i);
  }
  printf("%llu
",ans);
}
原文地址:https://www.cnblogs.com/shxnb666/p/11278430.html