P14079 [GESP202509 八级] 最短距离 题解
P14079 [GESP202509 八级] 最短距离
题意
给定一个包含 101810^{18}1018 个点的无向完全图,如果两个点的编号互质,那么连接两点的边边权为 ppp,否则为 qqq。给出 nnn 个询问,每次求两点 aia_{i}ai 和 bib_{i}bi 间的最短路径长度(1≤ai,bi≤1091\le a_{i},b_{i}\le 10^91≤ai,bi≤109)。
题解
赛时差点被诈骗了。
如果 aia_{i}ai 与 bib_{i}bi 互质,那么要么走直连的边,答案为 ppp,要么另走其他若干边权为 qqq 的边,这时显然最少走两条边。走两条边可以吗?因为 ai×bi≤1018a_{i}\times b_{i}\le 10^{18}ai×bi≤1018,所以显然可以走 ai→ai×bi→bia_{i}\to a_{i}\times b_{i}\to b_{i}ai→ai×bi→bi。最终答案即为 min(p,2q)\min(p,2q)min(p,2q)。
同理,如果 aia_{i}ai 与 bib_{i}bi 不互质,可以走直连边,也可以走 ai→1→bia_{i}\to 1\to b_{i}ai→1→bi。最终答案即为 min(2p,q)\min(2p,q)min(2p,q)。
特别的,如果 ai=bia_{i}= b_{i}ai=bi,则答案为 0。如果 ai=1a_{i}=1ai=1 或 bi=1b_{i}=1bi=1,则答案只能是 ppp。
代码
#include<iostream>
#include<algorithm>
using namespace std;
int n,p,q,a,b;
int main()
{ios::sync_with_stdio(0);cin.tie(0),cout.tie(0);cin>>n>>p>>q;while(n--){cin>>a>>b;if(a==b) cout<<"0\n";else if(a==1||b==1) cout<<p<<"\n";else if(__gcd(a,b)==1) cout<<min(p,2*q)<<"\n";else cout<<min(q,2*p)<<"\n";}return 0;
}