落谷 P3403 跳樓機(同餘最短路)
阿新 • • 發佈:2018-11-06
這道題和裸的同餘最短路思路是相同的,對於演算法的介紹請轉至蒟蒻(我)的另一篇題解:
https://blog.csdn.net/zzk_233/article/details/83419118
但是這道題有一些不同,起點是1,所以跑最短路的時候要把1先推入佇列,
而且dis[1]=1,因為雖然他是第一個,但是它要求的大小還是1。
其餘還是一樣的。
PS:一定要取模!!!最開始的1也要!!這是個坑點。
#include<cstdio> #include<cmath> #include<algorithm> #include<cstring> #include<queue> using namespace std; typedef long long ll; ll zans;int n; ll dis[500005],val[500005]; bool used[500005]; ll maxv=0x3f3f3f3f3f3f3f3fll; void spfa() { memset(dis,0x3f,sizeof(dis)); dis[1%maxv]=1; queue<int>M; M.push(1%maxv); used[1%maxv]=1; while(!M.empty()) { int u=M.front(); M.pop(); for(int i=1;i<=n;i++) { int y=(u+val[i])%maxv; if(dis[y]>dis[u]+val[i]) { dis[y]=dis[u]+val[i]; if(!used[y]) { used[y]=1; M.push(y); } } } used[u]=0; } } ll query(ll x) { ll ans=0; for(int i=0;i<maxv;i++) { if(dis[i]<=x)ans+=(x-dis[i])/maxv+1; } return ans; } int main() { n=3;scanf("%lld",&zans); for(int i=1;i<=n;i++) { scanf("%lld",&val[i]); if(!val[i])i--,n--; maxv=min(maxv,val[i]); } spfa(); printf("%lld",query(zans)); return 0; }