原文链接https://www.cnblogs.com/zhouzhendong/p/SRM704-800.html
题解
考虑构造一个 $n = 20$ 的图。
先把所有 $i$ 都连向 $i-1$ ,对于所有 $i,j(1leq i<j<n)$,加边 $i->j$。
设 $f(i)$ 表示从点 $i$ 开始经过 $icdots n-1$ 这些点的路径条数,则:
$$f(19) = f(18) = 1$$
$$forall 1leq i<18,f(i) = 2^{17-i}$$
证明:
$f(19)=f(18)=1$ 显然。
假设现在从点 $a$ 走到了点 $b(a<b)$,为了经过 $a,b$ 之间的点,接下来只能从 $b$ 往回走,直到走到 $a+1$,接下来只能往标号更大的节点走,而且 $a+1,a+2,cdots b-1,b$ 已经被经过了,所以接下来的方案数就是 $f(b)$ 。所以 $forall 1leq i<18,f(i) = sum_{j=i+1}^{18} f(j)=2^{17-i}$ 。
对于节点0的连法就简单了,我们既然得到了这么多形如 $2^t$ 的 $f(i)$ ,那么直接将 $k$ 转成二进制表示之后连一下就好了。
代码
#include <bits/stdc++.h> using namespace std; class HamiltonianConstruction { public: vector<string> construct(int k); }gg; vector<string> HamiltonianConstruction::construct(int k) { vector<string> g; int n=20; string s=""; for (int i=0;i<20;i++) s+="N"; g.clear(); for (int i=0;i<20;i++) g.push_back(s); for (int i=1;i<20;i++){ g[i][i-1]='Y'; for (int j=i+1;j<20-1;j++) g[i][j]='Y'; } g[18][19]='Y'; int c=17; while (k){ if (k&1) g[0][c]='Y'; k>>=1,c--; } return g; }