D. Friendly Spiders
By xiaruize
p.s.严厉谴责出题人在题目页面放蜘蛛啊,很难受qwq
思路
暴力建图显然需要 O(n2) , 无法通过本题
考虑是否可以优化, 发现同样的公因子可能被建多条边, 导致边数达到 n2 级别
如何解决这个问题? 可以对于每个公因子建一个点, 将所有有这个因子的数全部与这个点连边, 入边边权为 1 , 出边为 0
进一步优化, 可以发现, 只需要对质因子建点
对于这张图跑 Dijkstra 即可
Code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116
|
#include <bits/stdc++.h> using namespace std; #define int long long #define ull unsigned long long #define ALL(a) (a).begin(), (a).end() #define pb push_back #define mk make_pair #define pii pair<int, int> #define pis pair<int, string> #define sec second #define fir first #define sz(a) int((a).size()) #define rep(i, x, y) for (int i = x; i <= y; i++) #define repp(i, x, y) for (int i = x; i >= y; i--) #define Yes cout << "Yes" << endl #define YES cout << "YES" << endl #define No cout << "No" << endl #define NO cout << "NO" << endl #define debug(x) cerr << #x << ": " << x << endl #define double long double const int INF = 0x3f3f3f3f; const int MOD = 1000000007; const int N = 3e5 + 10;
int n; int a[N]; vector<pii> g[N * 2]; int fa[N * 2]; int siz = 0; int dis[N * 2]; int st, en; vector<int> res;
void dfs(int x) { res.pb(x); if (x < N) siz++; if (x == st) return; dfs(fa[x]); }
signed main() { cin >> n; for (int i = 1; i <= n; i++) { cin >> a[i]; int x = a[i]; for (int j = 2; j * j <= x; j++) { if (x % j == 0) { while (x % j == 0) x /= j; g[i].pb({j + N, 1}); g[j + N].pb({i, 0}); } } if (x != 1) { g[i].pb({x + N, 1}); g[x + N].pb({i, 0}); } } cin >> st >> en; priority_queue<pii, vector<pii>, greater<pii>> q; memset(dis, 0x3f, sizeof(dis)); dis[st] = 0; q.push({0, st}); while (!q.empty()) { int x = q.top().sec, d = q.top().fir; q.pop(); if (dis[x] < d) continue; if (x == en) break; for (auto v : g[x]) { if (dis[v.fir] > dis[x] + v.sec) { dis[v.fir] = dis[x] + v.sec; fa[v.fir] = x; q.push({dis[v.fir], v.fir}); } } } if (dis[en] >= INF) { cout << "-1" << endl; return 0; } dfs(en); reverse(ALL(res)); cout << siz << endl; for (auto v : res) if (v < N) cout << v << ' '; return 0; }
|