CF1775D Friendly Spiders 题解
L0vely_NaiL0ng · · 题解
前言:翻了一下题解区,基本都是用质因子作为点建图的,其实可以直接拿给定的
首先预处理出每一个
这一步分解
代码中上述
我们从
注意到上面的思路基本就是暴力的最短路,关键就在于加粗的一行。我们发现如果
这时候可能有的读者发现了,你这只是共用了中间
所以我们证明了可以使用上面那种做法保证正确性。
分析复杂度:边数即为
code (代码极短,只有 1.1k ):
#include<bits/stdc++.h>
using namespace std;
const int N = 3e5 + 5;
int n, a[N], s, t, d[N], pre[N];
bool vis[N];
vector<int> p[N], q[N];
queue<int> qu;
stack<int> pu;
void print(int x) {
while (x != s) { pu.push(x); x = pre[x]; }
cout << s << " ";
while (!pu.empty()) { cout << pu.top() << " "; pu.pop(); }
}
int main() {
scanf("%d", &n);
for (int i = 1; i <= n; i++) scanf("%d", &a[i]);
scanf("%d%d", &s, &t);
for (int i = 1; i <= n; i++) {
if (a[i] != 1) {
p[i].push_back(a[i]);
q[a[i]].push_back(i);
}
for (int j = 2; j * j <= a[i]; j++) {
if (a[i] % j == 0) {
p[i].push_back(j);
p[i].push_back(a[i] / j);
q[j].push_back(i);
q[a[i] / j].push_back(i);
}
}
}
qu.push(s); d[s] = 1;
while (!qu.empty()) {
int x = qu.front(); qu.pop();
for (int i = 0; i < p[x].size(); i++) {
int y = p[x][i];
if (vis[y]) continue; vis[y] = 1;
for (int j = 0; j < q[y].size(); j++) {
int z = q[y][j];
if (d[z] == 0) {
d[z] = d[x] + 1; qu.push(z); pre[z] = x;
}
}
}
}
if (d[t] == 0) puts("-1");
else {
cout << d[t] << endl;
print(t);
}
}