P3403 跳樓機(同餘最短路+奇妙建圖)
阿新 • • 發佈:2022-04-04
題意
Srwudi 的家是一幢 h 層的摩天大樓。由於前來學習的蒟蒻越來越多,srwudi 改造了一個跳樓機,使得訪客可以更方便的上樓。
經過改造,srwudi 的跳樓機可以採用以下四種方式移動:
- 向上移動 x 層;
- 向上移動 y 層;
- 向上移動 z 層;
- 回到第一層。
一個月黑風高的大中午,DJL 來到了 srwudi 的家,現在他在 srwudi 家的第一層,碰巧跳樓機也在第一層。DJL 想知道,他可以乘坐跳樓機前往的樓層數。
思路
同餘最短路,很顯然的是,如果 層數\(h_0\)是可以抵達的,那麼\(h_0+k*x\)的所有樓層都是可以抵達的,那麼我們只有操作2和操作3,從他們可以抵達的最小的\(h\)
設 \(d_i\)為能夠到達的最低的 \(\bmod x = i\) 的樓層。
則有 \(i \stackrel{y}{\longrightarrow} (i+y)\bmod x\) 和 \(i\stackrel{z}{\longrightarrow} (i+z)\bmod x\)像這樣建圖後,\(d_i\)就相當於 \(0→i\) 的最短路,Dijkstra 即可
code
#include <bits/stdc++.h> using namespace std; typedef long long ll; typedef unsigned long long ull; //#pragma GCC optimize(3) #define pb push_back #define is insert #define PII pair<int,int> #define PLL pair<ll,ll> #define show(x) cerr<<#x<<" : "<<x<<endl; //mt19937 mt19937random(std::chrono::system_clock::now().time_since_epoch().count()); //ll getRandom(ll l,ll r){return uniform_int_distribution<ll>(l,r)(mt19937random);} const ll INF=0x3f3f3f3f3f3f3f3f;//2147483647; const int N=1e5+50,M=1e4+50; const ll mod=1e9+7; ll d[N];int head[N]; bool vis[N]; struct node { int to,next; ll dis; }e[N<<1]; int cnt=0; void add_edge( int u, int v, ll d ){ cnt++; e[cnt].dis=d; e[cnt].to=v; e[cnt].next=head[u]; head[u]=cnt; } priority_queue<pair<ll,int>,vector<pair<ll,int>>,greater<pair<ll,int>>>q; void dijkstra(){ int s=1; memset(d,INF,sizeof(d)); memset(vis,0,sizeof(vis)); d[s]=1; q.push(make_pair(0,s)); while(!q.empty()){ int x=q.top().second;q.pop(); if(vis[x])continue; vis[x]=1; for(int i=head[x];i;i=e[i].next){ int y=e[i].to; if(d[y]>d[x]+e[i].dis){ d[y]=d[x]+e[i].dis; if(!vis[y])q.push(make_pair(d[y],y)); } } } } ll h,x,y,z; void solve() { cin>>h>>x>>y>>z; if(x==1||y==1||z==1){ cout<<h; return ; } for(int i=0;i<x;i++){ add_edge(i,(i+y)%x,y); add_edge(i,(i+z)%x,z); } dijkstra(); ll ans=0; for(int i=0;i<x;i++){ //cout<<"d["<<i<<"]"<<"="<<d[i]<<endl; if(d[i]<=h)ans+=(h-d[i])/x+1; } cout<<ans; } signed main(){ ios::sync_with_stdio(0);cin.tie(0);cout.tie(0); int __=1;//cin>>__; while(__--){ solve(); } return 0; }