1. 程式人生 > 實用技巧 >同餘最短路

同餘最短路

跳樓機

#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<queue>
#include<cstdlib>
#include<stack>
using namespace std;
typedef long long LL;
LL h,d[
100005],cnt; int x,y,z,hd[100005],a[15]; struct Edge{ LL to, nxt, w; }edge[2000005]; struct Point{ LL val; int s; Point(){} Point(LL VAL,int S){val=VAL,s=S;} bool operator < (Point another) const { return val>another.val; }// }; void add(int u, int v, int w){ cnt++; edge[cnt].to
= v; edge[cnt].nxt = hd[u]; edge[cnt].w = w; hd[u] = cnt; } void Dijkstra(LL s){ memset(d,63,sizeof d); d[0]=0; priority_queue<Point> Q; Q.push(Point(0,s)); while(!Q.empty()){ Point now=Q.top(); Q.pop(); int p=now.s; LL val=now.val;
if(val<d[p]) continue; for(int i = hd[p]; i; i = edge[i].nxt){ int v = edge[i].to; if(d[v] > d[p] + edge[i].w){//err: (dis[u] + edge[i].w)%x d[v] = d[p] + edge[i].w; Q.push(Point(d[p] + edge[i].w, v)); } } } } int main(){ scanf("%lld %d %d %d",&h,&x,&y,&z); a[1]=x,a[2]=y,a[3]=z; sort(a+1,a+4); x=a[1],y=a[2],z=a[3]; if(x == 1 || y==1 || z==1) {printf("%lld",h);return 0;} ////所以0 - x 這些點和其他點之間已知的的關係 for(int i=0;i<x;++i) add(i, (i + y)%x, y), add(i, (i + z)%x, z); Dijkstra(0); LL ans=0; for(int i=0;i<x;++i) if(d[i]-1<=h) ans+=(h-d[i]-1)/x+1; printf("%lld",ans); return 0; }
View Code