【CF325E】The Red Button

来源:互联网 发布:复制信息打开手机淘宝 编辑:程序博客网 时间:2024/06/03 20:05

一个n个点的图,标号0 ~ n-1,第i个点向2 * i和2 * i + 1连边,构造哈密顿回路。

首先发现n为奇数无解。考虑转换为欧拉回路,将2 * i 与2 * i + 1合并为一点,这样点就转化为边了。

#include <iostream>#include <cstdio>#include <algorithm>#include <cstring>#include <cmath>#define Rep(i, x, y) for (int i = x; i <= y; i ++)#define Dwn(i, x, y) for (int i = x; i >= y; i --)#define RepE(i, x) for(int i = pos[x]; i; i = g[i].nex)using namespace std;typedef long long LL;const int N = 200005;struct Edge { int x, y, z, nex; } g[N * 2];int n, m, pos[N], sz, p[N], ans[N], az; bool vis[N];void Init(int x, int y, int z) { g[++ sz] = (Edge) { x, y, z, pos[x] }, pos[x] = sz; }void Dfs(int x) {RepE(i, x) if (!vis[i]) {vis[i] = 1, Dfs(g[i].y), p[++ m] = i;}}int main(){scanf ("%d", &n);if (n % 2) { puts("-1"); return 0; }Rep(i, 0, n / 2 - 1) Init(i, ((i * 4 % n) / 2 + 1) % (n/2), 1), Init(i, (i * 4 % n) / 2, 0);Dfs(0);Dwn(i0, m, 1) {int i = p[i0], x = g[i].x, y = g[i].y;ans[++ az] = 2 * x + g[i].z;}Rep(i, 1, az) printf("%d ", ans[i]);puts("0");return 0;}


0 0