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;
}

猜你喜欢

转载自www.cnblogs.com/sdfzhsz/p/9276020.html