最短路模型-跳楼机-洛谷P3403

第一次遇到这种数学题转化为图论的题目,与我一开始的想法相同,将其中一个变量与另外两个变量分离开来,便于处理。由于以前一直认为SPFA会被卡,所以使用了堆优化的Dijkstra,结果超时了,为什么呢?因为我们构造出来的图是一张很稀疏的图,在这种图上Dijkstra与SPFA比较是比较劣的。由于图是我们自己构造的,并不是什么专门用来卡SPFA的网格图等等,所以可以使用SPFA,一定不会超时。(打破了我不要用SPFA的认识233)
另外,还是要注意边界情况,当x为1的时候并不存在模x意义下能够跳到1楼的情况,因此在这种情况下dis[1]是不会被纳入计算的,答案就变成了0,但其实是题中所给的h。

#include
#define rep(i,l,r) for(int i=(l);i<=(r);i++)
#define per(i,r,l) for(int i=(r);i>=(l);i--)
using namespace std;
typedef long long ll;
const int N=1e5+10;
int x,y,z;
int to[N*2],nxt[N*2],w[N*2],head[N],len;
ll h,ans,dis[N];
inline void addedge(int a,int b,int ww){ nxt[++len]=head[a]; head[a]=len; to[len]=b; w[len]=ww; }
queue<int> q;
bool inq[N];
int main(){
	cin>>h>>x>>y>>z;
	if(x==1){
		cout<<h;
		return 0;
	}
	rep(i,0,x-1) addedge(i,(i+y)%x,y),addedge(i,(i+z)%x,z);
	memset(dis,0x3f,sizeof(dis)); dis[1]=1;
	q.push(1); inq[1]=true;
	while(!q.empty()){
		int h=q.front(); q.pop(); inq[h]=false;
		for(int i=head[h];i!=0;i=nxt[i]){
			if(dis[h]+w[i]<dis[to[i]]){
				dis[to[i]]=dis[h]+w[i];
				if(!inq[to[i]]){
					inq[to[i]]=true;
					q.push(to[i]);
				}
			}
		}
	}
	rep(i,0,x-1) if(dis[i]<=h) ans+=(h-dis[i])/x+1;
	cout<<ans;
	return 0;
}

你可能感兴趣的:(比赛,图论-最短路)