P14079 [GESP202509 八级] 最短距离

GESP8 冲刺课堂页:先建模,再压缩状态,最后读代码。

一、先回答问题

结论

完全图边权只有 p/q,两点最短路只需比较直达和一次中转。

容易误入的路

看到 N=10^18 就想建图或跑最短路,实际只能做数学分类。

二、核心观察

建模与压缩

两点互质时直达是 p,不互质时直达是 q;巨大点集保证合适中间点存在。

为什么不丢答案:p、q 都为正,超过两条边不会优于某个直达或两段中转方案。

gcd(a,b) 直达 一次中转

三、互动演示

步骤1
关键状态 A-
关键状态 B-
答案/目标-
复杂度看表
课堂动作手推

四、自己选答案

问题 1

为什么不用三条边?

问题 2

a 或 b 为 1 时为什么特判?

五、手推结果

情况直达可选绕路答案
a=b0-0
gcd=1p2qmin(p,2q)
gcd>1q2pmin(q,2p)

课堂要求:每题先说清对象、关系、保留的信息、压缩掉的信息,再写代码。

六、C++14 参考代码

#include <bits/stdc++.h>
using namespace std;

typedef long long ll;

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    
    int n;
    ll p, q;
    if (!(cin >> n >> p >> q)) return 0;
    
    while (n--) {
        ll a, b;
        cin >> a >> b;
        
        if (a == b) {
            cout << 0 << "\n";
        } else if (a == 1 || b == 1) {
            cout << p << "\n";
        } else {
            ll g = __gcd(a, b);
            if (g == 1) {
                // 互质:直达为 p,或者绕路找不互质的点为 2q
                cout << min(p, 2 * q) << "\n";
            } else {
                // 不互质:直达为 q,或者绕路找互质的点为 2p
                cout << min(q, 2 * p) << "\n";
            }
        }
    }
    
    return 0;
}