D. Friendly Spiders

By xiaruize

p.s.严厉谴责出题人在题目页面放蜘蛛啊,很难受qwq

思路

暴力建图显然需要 O(n2)O(n^2) , 无法通过本题

考虑是否可以优化, 发现同样的公因子可能被建多条边, 导致边数达到 n2n^2 级别

如何解决这个问题? 可以对于每个公因子建一个点, 将所有有这个因子的数全部与这个点连边, 入边边权为 11 , 出边为 00

进一步优化, 可以发现, 只需要对质因子建点

对于这张图跑 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
/*
Name:
Author: xiaruize
Date:
*/
#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;

// bool st;
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;
// bool en;

void dfs(int x)//找路径
{
res.pb(x);
if (x < N)
siz++;
if (x == st)
return;
dfs(fa[x]);
}

signed main()
{
// freopen(".in","r",stdin);
// freopen(".out","w",stdout);
// cerr<<(&en-&st)/1024.0/1024.0<<endl;
// auto t_1=chrono::high_resolution_clock::now();
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;
//Dijkstra
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 << ' ';
// auto t_2=chrono::high_resolution_clock::now();
// cout <<". Elapsed (ms): " << chrono::duration_cast<chrono::milliseconds>(t_2 - t_1).count() << endl;
return 0;
}