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;
}
posted @ 2021-10-18 21:36  lahlah  阅读(29)  评论(0编辑  收藏  举报