[浅谈] 同余最短路
所谓同余最短路,就是把余数相同的情况归为一类,然后找到形成这种情况的最短路径。
我们假设只能跳
那么现在再加个可以跳
我们可以把每类数看做一个点,假设目前点为
以此类推,建完所有边后,跑一边
点击查看代码
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=5e5+110;
int read(){
int x=0,f=1;char c=getchar();
while(c>'9' || c<'0'){if(c=='-')f=-1;c=getchar();}
while(c>='0' && c<='9'){x=(x<<1)+(x<<3)+(c^48);c=getchar();}
return x*f;
}
int h,x,y,z;
int dis[N],head[N],to[N*5],last[N*5],w[N*5],tot;
void add(int u,int v,int t){to[++tot]=v,w[tot]=t,last[tot]=head[u],head[u]=tot;return;}
struct node{
int dis,u;
bool operator<(const node A)const{return A.dis<dis;}
};
void dijkstra(){
memset(dis,0x3f,sizeof(dis));dis[0]=0;
priority_queue<node>q;q.push((node){0,0});
while(!q.empty()){
int u=q.top().u;q.pop();
for(int i=head[u];i;i=last[i]){
int v=to[i];
if(dis[v]>dis[u]+w[i]){
dis[v]=dis[u]+w[i];
q.push((node){dis[v],v});
}
}
}
return;
}
signed main(){
h=read()-1,x=read(),y=read(),z=read();
for(int i=0;i<x;i++){
add(i,(i+y)%x,y);
add(i,(i+z)%x,z);
}
dijkstra();int ans=0;
for(int i=0;i<x;i++)if(h>=dis[i])ans+=(h-dis[i])/x+1;
printf("%lld\n",ans);
return 0;
}
把
点击查看代码
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=5e5+110;
int read(){
int x=0,f=1;char c=getchar();
while(c>'9' || c<'0'){if(c=='-')f=-1;c=getchar();}
while(c>='0' && c<='9'){x=(x<<1)+(x<<3)+(c^48);c=getchar();}
return x*f;
}
int n,l,r,a[N];
int dis[N],head[N],to[N*13],last[N*13],w[N*13],tot;
void add(int u,int v,int t){to[++tot]=v,w[tot]=t,last[tot]=head[u],head[u]=tot;return;}
struct node{
int dis,u;
bool operator<(const node A)const{return A.dis<dis;}
};
void dijkstra(){
memset(dis,0x3f,sizeof(dis));dis[0]=0;
priority_queue<node>q;q.push((node){0,0});
while(!q.empty()){
int u=q.top().u;q.pop();
for(int i=head[u];i;i=last[i]){
int v=to[i];
if(dis[v]>dis[u]+w[i]){
dis[v]=dis[u]+w[i];
q.push((node){dis[v],v});
}
}
}
return;
}
signed main(){
n=read(),l=read(),r=read();
for(int i=1;i<=n;i++)a[i]=read();
for(int i=0;i<a[1];i++){
for(int j=2;j<=n;j++)
add(i,(i+a[j])%a[1],a[j]);
}
dijkstra();int ans=0;
for(int i=0;i<a[1];i++){
if(r>=dis[i])ans+=(r-dis[i])/a[1]+1;
if(l-1>=dis[i])ans-=(l-1-dis[i])/a[1]+1;
}
printf("%lld\n",ans);
return 0;
}
还是按
点击查看代码
#include<bits/stdc++.h>
using namespace std;
const int N=3010;
int read(){
int x=0,f=1;char c=getchar();
while(c>'9' || c<'0'){if(c=='-')f=-1;c=getchar();}
while(c>='0' && c<='9'){x=(x<<1)+(x<<3)+(c^48);c=getchar();}
return x*f;
}
int n,m,k,bk[N],a[N];
int gcd(int a,int b){
return b==0?a:gcd(b,a%b);
}
int dis[N],head[N],to[N*3000],last[N*3000],w[N*3000],tot;
void add(int u,int v,int t){to[++tot]=v,w[tot]=t,last[tot]=head[u],head[u]=tot;return;}
struct node{
int dis,u;
bool operator<(const node A)const{return A.dis<dis;}
};
void dijkstra(){
memset(dis,0x3f,sizeof(dis));dis[0]=0;
priority_queue<node>q;q.push((node){0,0});
while(!q.empty()){
int u=q.top().u;q.pop();
for(int i=head[u];i;i=last[i]){
int v=to[i];
if(dis[v]>dis[u]+w[i]){
dis[v]=dis[u]+w[i];
q.push((node){dis[v],v});
}
}
}
return;
}
int main(){
n=read(),m=read();
for(int i=1;i<=n;i++){
int t=read();
for(int i=t;i>=max(1,t-m);i--)bk[i]=1;
}
for(int i=1;i<=3000;i++)
if(bk[i])a[++k]=i;
int t=a[1];
for(int i=2;i<=k;i++)t=gcd(t,a[i]);
if(t!=1 || a[1]==1){
printf("-1\n");
return 0;
}
for(int u=0;u<a[1];u++)
for(int i=2;i<=k;i++)
add(u,(u+a[i])%a[1],a[i]);
dijkstra();int ans=0;
for(int i=0;i<a[1];i++){
ans=max(ans,dis[i]-a[1]);
}
printf("%d\n",ans);
return 0;
}
把数按
- 如果把个位
,余数加一(或归零),答案加一,建边 。 - 如果乘
, 答案不变,建边 。
点击查看代码
#include<bits/stdc++.h>
using namespace std;
const int N=1e5+110;
int read(){
int x=0,f=1;char c=getchar();
while(c>'9' || c<'0'){if(c=='-')f=-1;c=getchar();}
while(c>='0' && c<='9'){x=(x<<1)+(x<<3)+(c^48);c=getchar();}
return x*f;
}
int k;
int dis[N],head[N],to[N*3],last[N*3],w[N*3],tot;
void add(int u,int v,int t){to[++tot]=v,w[tot]=t,last[tot]=head[u],head[u]=tot;return;}
struct node{
int dis,u;
bool operator<(const node A)const{return A.dis<dis;}
};
void dijkstra(){
dis[0]=2e9;
for(int i=1;i<k;i++){
int j=i;
while(j)dis[i]+=j%10,j/=10;
}
priority_queue<node>q;
for(int i=1;i<k;i++)q.push((node){dis[i],i});
while(!q.empty()){
int u=q.top().u;q.pop();
for(int i=head[u];i;i=last[i]){
int v=to[i];
if(dis[v]>dis[u]+w[i]){
dis[v]=dis[u]+w[i];
q.push((node){dis[v],v});
}
}
}
return;
}
int main(){
k=read();
for(int i=0;i<k;i++){
add(i,(i+1)%k,1);
add(i,(i*10)%k,0);
}
dijkstra();
printf("%d\n",dis[0]);
return 0;
}
标签:
算法 同余最短路
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!