POJ3539 Elevator

本来用vector写的,结果T了,您还卡常啊....
这类题叫同余类bfs,因为h太大了,我们不可能枚举(雾)
把h层弄成膜a下剩余系,然后向每个剩余系(x+b)%a连权为b的边,(x+c)%a连权c的边,spfa一发,然后随便搞一下。
long long!

#include <iostream>
#include <cstdio>
#include <vector>
#include <cstring>
#include <queue>
using namespace std;
struct edge{int to,nxt,val;}e[100005<<1];
int ecnt=0,head[100005];
void add(int bg,int ed,int val){e[++ecnt].nxt=head[bg];e[ecnt].to=ed;e[ecnt].val=val;head[bg]=ecnt;}
long long a,b,c,dis[100005];
long long h;
bool vis[100005];
queue<int>q;
void spfa() {
	q.push(1%a);
	memset(dis,0x3f,sizeof dis);
	dis[1%a]=1;
	vis[1%a]=1;
	while(!q.empty()) {
		int u=q.front();
		q.pop();
		vis[u]=0;
		for(int i=head[u]; i; i=e[i].nxt) {
			int v=e[i].to;
			if(dis[u]+e[i].val<dis[v]) {
				dis[v]=dis[u]+e[i].val;
				if(!vis[v]) q.push(v),vis[v]=1;
			}
		}
	}
}
int main() {
	cin>>h>>a>>b>>c;
	if(a>b) swap(a,b);
	if(a>c) swap(a,c);
	for(int i=0; i<a; i++) {
		add(i,(i+b)%a,b);
		add(i,(i+c)%a,c);
	}
	spfa();
	long long ans=0;
	for(int i=0;i<a;i++) if(dis[i]<=h)ans+=(h-dis[i])/a+1;
	cout<<ans;
}
posted @ 2018-07-07 00:29  SWHsz  阅读(188)  评论(0编辑  收藏  举报