图论:spfa求同余最短路

题目来自:点击这里

#include<cstring>
#include<iostream>
#include<queue>
#include<cstdio>
#include<algorithm>
using namespace std;
typedef long long ll;
const ll inf = 0x3f3f3f3f;
struct edge{
    
    
 	ll to,w,next;
}kkk[1000050*2];
ll head[100050],dis[100050],vis[100050],numedge=0,n;
ll x1,x2,x3;
ll ans=0;
void addedge(ll u,ll v,ll w){
    
    
 	kkk[++numedge].to=v;
 	kkk[numedge].w=w;
 	kkk[numedge].next=head[u];
 	head[u]=numedge;
}
void spfa(ll s){
    
    
 	queue<ll> q;
 	dis[s]=1,vis[s]=1;
 	q.push(s);
 	while(!q.empty()){
    
    
  		ll u=q.front();
  		q.pop();
  		vis[u]=0;
  		for(ll i=head[u];i;i=kkk[i].next){
    
    
   			ll v=kkk[i].to;
   			if(dis[v]>dis[u]+kkk[i].w){
    
    
    			dis[v]=dis[u]+kkk[i].w;
    			if(!vis[v]){
    
    
     				vis[v]=1;
     				q.push(v);
    			}
   			}//题目保证无负环
  		}
 	}
}
int main()
{
    
    
 	scanf("%lld",&n);
 	memset(dis,inf,sizeof(dis));
 	scanf("%lld%lld%lld",&x1,&x2,&x3);
 	if(x1==1||x2==1||x3==1){
    
    
 		printf("%lld",n);
 		return 0;
	 }
 	for (ll i = 0; i < x1; ++i) {
    
    
    	addedge(i, (i + x3) % x1, x3);
    	addedge(i, (i + x2) % x1, x2);
  	}
 	spfa(1);
 	for(ll i=0;i<x1;++i){
    
    
    	if(n>=dis[i]) {
    
    
    		ans+=(n-dis[i])/x1+1;	
		}
  	}
	printf("%lld",ans);
 	return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_45695839/article/details/109515226