当前位置: 代码迷 >> 综合 >> 『最短路·裴蜀定理』CF510D Fox And Jumping
  详细解决方案

『最短路·裴蜀定理』CF510D Fox And Jumping

热度:89   发布时间:2023-12-17 10:40:15.0

P r o b l e m \mathrm{Problem} Problem

给出 n n n 张卡片,分别有 l i l_i li? c i c_i ci?

在一条无限长的纸带上,你可以选择花 c i c_i ci? 的钱来购买卡片 i i i,从此以后可以向左或向右跳 l i l_i li? 个单位。

问你至少花多少元钱才能够跳到纸带上全部位置。若不行,输出 ? 1 -1 ?1


S o l u t i o n \mathrm{Solution} Solution

若对于数字 a a a 和数字 b b b ,根据裴蜀定理,方程 a x + b y = c ( g c d ( a , b ) ∣ c ) ax+by=c(\mathrm{gcd}(a,b)|c) ax+by=c(gcd(a,b)c)恒有解。

因此若我们能拼出 x x x 的任何倍数,我们就可以用 c i c_i ci? 拼出 gcd ? ( x , l i ) \gcd (x,l_i) gcd(x,li?) 任何数。

这对应了一个最短路模型,我们以 0 0 0 跑最短路即可,主要要用map或哈希存储。


C o d e \mathrm{Code} Code

#include <bits/stdc++.h>
#define int long longusing namespace std;
const int N = 2e5;int n;
int c[N], l[N];
map < int, int > vis, dis;
priority_queue < pair<int, int> > q;int read(void)
{
    int s = 0, w = 0; char c = getchar();while (!isdigit(c)) w |= c == '-', c = getchar();while (isdigit(c)) s = s*10+c-48, c = getchar();return w ? -s : s;
}int gcd(int a, int b) {
    if (b == 0) return a;return gcd(b, a % b);
}int Dijkstra(void)
{
    q.push({
    dis[0] = 0LL, 0LL});while (q.size()){
    int x = q.top().second; q.pop();if (vis[x]) continue; vis[x] = 1;if (x == 1) return dis[1];for (int i=1;i<=n;++i){
    int y = gcd(l[i], x);if (dis.count(y) == 0) dis[y] = 1e18;if (dis[x] + c[i] < dis[y]) {
     dis[y] = dis[x] + c[i];q.push({
    -dis[y], y});} }}return -1;
}signed main(void)
{
    n = read();for (int i=1;i<=n;++i) l[i] = read();for (int i=1;i<=n;++i) c[i] = read();cout << Dijkstra() << endl;return 0;
}
  相关解决方案