int n, m, cnt; int u[kMaxN], v[kMaxN], p[kMaxN], q[kMaxN], deg[kMaxN], bel[kMaxN]; bool del[kMaxN]; std::vector<int> G[kMaxN], T[kMaxN]; std::set<int> chry[kMaxN];
voidinit(){ cnt = 0; for (int i = 1; i <= n; ++i) G[i].clear(), T[i].clear(), chry[i].clear(), p[i] = q[i] = deg[i] = bel[i] = del[i] = 0; }
voidsolve1(){ // 求出度数为 n - 1 的点 std::set<std::pair<int, int>> st; for (int i = 1; i <= n; ++i) st.emplace(deg[i] = G[i].size(), i); int now = n; for (int i = 1; i <= n; ++i) { if (prev(st.end())->first != now - 1) break; int u = prev(st.end())->second; st.erase(prev(st.end())); p[u] = q[u] = ++cnt, --now, del[u] = 1; for (auto v : G[u]) { if (!del[v]) { st.erase({deg[v], v}); --deg[v]; st.emplace(deg[v], v); } } } for (int i = 1; i <= n; ++i) G[i].clear(); for (int i = 1; i <= m; ++i) if (!del[u[i]] && !del[v[i]]) G[u[i]].emplace_back(v[i]), G[v[i]].emplace_back(u[i]); }
voidsolve2(){ // 求出补图生成森林 std::set<int> st; for (int i = 1; i <= n; ++i) { if (!del[i]) st.emplace(i); std::sort(G[i].begin(), G[i].end()); } std::function<void(int)> dfs = [&] (int u) { std::vector<int> vec; for (auto v : st) if (std::find(G[u].begin(), G[u].end(), v) == G[u].end()) vec.emplace_back(v), T[u].emplace_back(v), T[v].emplace_back(u); for (auto v : vec) st.erase(v); for (auto v : vec) dfs(v); }; for (int i = 1; i <= n; ++i) { if (!del[i] && st.count(i)) { st.erase(i); dfs(i); } } }
voidsolve3(){ // 求出菊花划分 for (int i = 1; i <= n; ++i) { if (!del[i] && !bel[i]) { bool fl = 0; for (auto j : T[i]) fl |= !bel[j]; if (fl) { chry[i].emplace(i), bel[i] = i; for (auto j : T[i]) { if (!bel[j]) chry[i].emplace(j), bel[j] = i; } } else { int j = T[i][0]; if (chry[bel[j]].size() == 2) { chry[j].swap(chry[bel[j]]); bel[bel[j]] = j; for (auto x : T[j]) { if (!bel[x]) chry[j].emplace(x), bel[x] = j; } } else { chry[bel[j]].erase(j); bel[i] = bel[j] = i; chry[i].emplace(i), chry[i].emplace(j); } } } } int sum = cnt; for (int i = 1; i <= n; ++i) sum += chry[i].size(); for (int i = 1; i <= n; ++i) { if (chry[i].size()) { p[i] = cnt + 1; int now = 1; for (auto x : chry[i]) { if (x != i) p[x] = cnt + (++now); } q[i] = cnt + now; now = 0; for (auto x : chry[i]) { if (x != i) q[x] = cnt + (++now); } cnt += chry[i].size(); } } }
voiddickdreamer(){ std::cin >> n >> m; init(); for (int i = 1; i <= m; ++i) { std::cin >> u[i] >> v[i]; G[u[i]].emplace_back(v[i]), G[v[i]].emplace_back(u[i]); } solve1(), solve2(), solve3(); for (int i = 1; i <= n; ++i) std::cout << p[i] << " \n"[i == n]; for (int i = 1; i <= n; ++i) std::cout << q[i] << " \n"[i == n]; }