房间迷宫
题目链接https://www.cometoj.com/contest/33/problem/G
验证码:jwjtxdy
题目描述
鸡尾酒被困入了一个迷宫!
这个迷宫总共有n个房间组成,鸡尾酒初始在1号房间,n号房间为迷宫的出口。每进入一次第i个房间都需要缴纳ai的过路费(包括初始的一号房间)。每个房间有一张纸条和一个箱子。纸条上写着的数字di代表鸡尾酒下一个可以到达的房间编号。
鸡尾酒也可以选择花费bi的金钱打开箱子,箱子中有一个密码ci,打开箱子之后鸡尾酒可以移动到i+k号房间,其中c可被k整除。但如果i+k>n,则不能移动。
求鸡尾酒从走出迷宫的最小花费。若鸡尾酒无法走出迷宫,输出-1。
输入描述
输入第一行一个n,代表迷宫共有n个房间(n<2e5)
接下来有n行,每行包含四个整数ai,bi,ci,di,意义如题面所描述。其中(ai,bi,ci,di≤2e5)
输出描述
输出一行一个整数代表走出迷宫的最小花费。
样例输入 1
5
1 2 2 4
2 2 2 2
1 1 2 2
100 1 1 1
1 1 1 1
样例输出 1
6
这题显然是个最短路,我们只要注意存边的时候将c的因子囊括进来就好了,我们可以先筛选每个数的因子,利用埃氏筛同时加vector存因子:
for(int i=1; i<mac; ++i) {
for(int j = i; j<mac; j+=i) {
yinzi[j].push_back(i);
}
}
存边的时候还要注意i-i的距离为0,接下来就是没有什么好说的了,就是一个优先队列+vector优化的迪杰斯特拉最短路:
#include <cstdio>
#include <vector>
#include <queue>
#include <iostream>
#include <cmath>
#include <cstring>
#include <map>
#define ll long long
#define inf 999999999999
#define mac 200050
using namespace std;
struct node {
int to, cost;
};
struct node2 {
int id;
ll d;
bool friend operator < (node2 n1, node2 n2) {
return n1.d > n2.d;
}
};
vector<node>g[mac];
vector<int>yinzi[mac];
ll dis[mac];
int vis[mac];
int a[mac],b[mac],c[mac],d[mac];
void dj(int s);
int main()
{
int n;
for(int i=1;i<mac;++i) {
for(int j = i;j<mac;j+=i) {
yinzi[j].push_back(i);
}
}
scanf ("%d",&n);
for (int i=1; i<=n; i++){
scanf ("%d%d%d%d",&a[i],&b[i],&c[i],&d[i]);
}
for (int i=1; i<=n; i++){
node n1,n2;
if (d[i]!=i){
n1.to=d[i];
n1.cost=a[d[i]];
g[i].push_back(n1);
}
for (int j=0; j<yinzi[c[i]].size(); j++){
int pp=yinzi[c[i]][j];
if (pp+i>n) break;
n1.to=i+pp;
n1.cost=a[i+pp]+b[i];
g[i].push_back(n1);
}
}
for (int i=1; i<=n; i++) dis[i]=inf;
dj(1);
if (dis[n]==inf) printf ("-1\n");
else printf ("%lld\n",dis[n]+a[1]);
return 0;
}
void dj(int s)
{
priority_queue<node2>q;
dis[s]=0;
node2 k;
k.id=s;
k.d=0;
q.push(k);
while (!q.empty()){
node2 ks=q.top();q.pop();
int now=ks.id;
if (vis[now]) continue;
vis[now]=1;
for (int i=0; i<g[now].size(); i++){
if (!vis[g[now][i].to] && (ll)g[now][i].cost+dis[now]<dis[g[now][i].to]){
dis[g[now][i].to]=(ll)g[now][i].cost+dis[now];
node2 kis;
kis.d=dis[g[now][i].to],kis.id=g[now][i].to;
q.push(kis);
}
}
}
}