题意:https://www.luogu.com.cn/problem/CF1775D
思路:首先我们将每个点和他的质因子建图,将点到质因子的边权为0,质因子到点的边权为1,然后跑dij就可以求出两点的距离,那么如何记录路径呢,我们只需要在dij点更新距离是记录一下他的前驱节点即可。
/*keep on going and never give up*/
#include<cstdio>
#include<iostream>
#include<queue>
#include<algorithm>
using namespace std;
#define int long long
typedef pair<int, int> pii;
#define lowbit(x) x&(-x)
#define endl '\n'
#define wk is zqx ta die
int a[300005];
vector<pii> pl[600006];
int dis[600006];
int pre[600006];
vector<int> phi[300005];
signed main() {
std::ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int n;
cin >> n;
for (int i = 2; i <= 300000; i++) {
if (phi[i].empty()) {
for (int j = i; j <= 300000; j += i) {
phi[j].push_back(i);
}
}
}
for (int i = 1; i <= n + 300000; i++) {
dis[i] = 1e18;
pre[i] = 0;
}
for (int i = 1; i <= n; i++) {
cin >> a[i];
for (auto g : phi[a[i]]) {
pl[i].push_back({g + n, 0});
pl[g + n].push_back({i, 1});
}
}
int s, t;
cin >> s >> t;
queue<int> p;
p.push(s);
dis[s] = 1;
while (!p.empty()) {
int y = p.front();
p.pop();
for (auto g : pl[y]) {
if (g.first > n) {
if (dis[g.first] > dis[y]) {
dis[g.first] = dis[y];
pre[g.first] = y;
p.push(g.first);
}
} else {
if (dis[g.first] > dis[y] + 1) {
dis[g.first] = dis[y] + 1;
pre[g.first] = y;
p.push(g.first);
}
}
}
}
if (dis[t] == 1e18) {
cout << "-1" << endl;
} else {
cout << dis[t] << endl;
vector<int> ans;
while (t) {
if (t <= n) {
ans.push_back(t);
}
t = pre[t];
}
reverse(ans.begin(), ans.end());
for (auto g : ans) {
cout << g << " ";
}
cout << endl;
}
return 0;
}