您的位置:首页 > 其它

POJ 3539 同余类BFS

2015-10-10 11:29 176 查看
【残缺地理解同余类BFS】

题意:一栋h层的楼(h <= 10^18)的电梯上一共4个按钮:上升a层,上升b层,上升c层(a, b, c <= 10^5),和下降至1层,初始在1层,问有多少层通过电梯可达。

第一次做同余类BFS,之前处于一个不明觉厉的状态,现在稍微理解了一点点。同余类BFS可以看作一种求最短路的方法,在BFS的基础上加个取模。然而蒟蒻理解的并不彻底,先拿这道题说说吧。

假如我们现在电梯的运行是在模a的同余类下进行,就是说,如果可以达到i,那么i+k*a都可以达到。

可以想象一共有a个节点,每个节点有两条有向边(有向无向并不重要),长度为b,c,初始时我们在节点1(1层),设d[i]表示1到i的最短路。

思考如果d[i] <= h,就是说可以在h层之前到达第j层,j % a == i,那么j+k*a也是可以到达,对于每个d[i] <= h的i都求出k,求和即为答案。

#include <cstdio>
#include <algorithm>
#include <cstring>
#include <queue>
using namespace std;
typedef long long L;

L h, a, b, c, ans, d[100005];
bool inq[100005];
queue <L> q;

int main()
{
scanf("%lld %lld %lld %lld", &h, &a, &b, &c);
if(a > b) swap(a, b); if(a > c) swap(a, c);

memset(d, 0x3f, sizeof d);
d[1%a] = 0;   q.push(1%a);
while(!q.empty())
{
L u = q.front(), v; q.pop(); inq[u] = 0;
if(d[v=(u+b)%a] > d[u] + b)
{
d[v] = d[u] + b;
if(!inq[v]){inq[v] = 1; q.push(v);}
}
if(d[v=(u+c)%a] > d[u] + c)
{
d[v] = d[u] + c;
if(!inq[v]){inq[v] = 1; q.push(v);}
}
}

for(L i = 0; i < a; i++) if(d[i] <= h)
{
ans += (h-d[i])/a + 1;
}
printf("%lld", ans);
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  poj