AT2306 [AGC010E] Rearranging
https://www.luogu.com.cn/problem/AT2306
和这道题有点像AT1984 [AGC001F] Wide Swap
对于已经确定的top图,只需要用优先队列做top排序即可
那么确定top图,只需要小的连向大的就行了
代码实现不难
code:
#include<bits/stdc++.h>
#define N 2050
using namespace std;
int gcd(int x, int y) {
return y? gcd(y, x % y) : x;
}
struct edge {
int v, nxt;
} e[N * N << 1];
int p[N], eid, in[N];
void init() {
memset(p, -1, sizeof p);
eid = 0;
}
void insert(int u, int v) { in[v] ++;
e[eid].v = v;
e[eid].nxt = p[u];
p[u] = eid ++;
}
vector<int> g[N];
int n, vis[N], a[N], ans[N];
void dfs(int u) {
vis[u] = 1;
for(int i = 0; i < g[u].size(); i ++) {
int v = g[u][i];
if(vis[v]) continue;
insert(u, v);
dfs(v);
}
}
priority_queue<int> q;
int main() {
init();
scanf("%d", &n);
for(int i = 1; i <= n; i ++) scanf("%d", &a[i]);
sort(a + 1, a + 1 + n);
for(int i = 1; i <= n; i ++)
for(int j = i + 1; j <= n; j ++)
if(gcd(a[i], a[j]) > 1) g[i].push_back(j), g[j].push_back(i);
for(int i = 1; i <= n; i ++) if(!vis[i]) dfs(i);
for(int i = 1; i <= n; i ++) if(!in[i]) q.push(i);
for(int i = 1; i <= n; i ++) {
int u = q.top(); q.pop();
ans[i] = a[u];
for(int j = p[u]; j + 1; j = e[j].nxt) {
int v = e[j].v;
if(!(-- in[v])) q.push(v);
}
}
for(int i = 1; i <= n; i ++) printf("%d ", ans[i]);
return 0;
}