CSES Hamiltonian Flights(状态压缩DP)
题意
求从$1$到节点$n$有多少条哈密顿通路
$n<=20$
题解
$n$只有$20$, 可以枚举, 使用状态压缩DP,
定义状态$dp[mask][i]$, 其中$mask$为已经访问过的点, $i$为当前访问的点,
状态转移: $dp[mask][i] = \sum_{v \in S}dp[mask/i][v]$, 当前节点$i$通过所有不含节点$i$且有邻接边的状态转移而来,
初始化: $dp[1][0] = 1$, 起点
参考代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44
| #include <bits/stdc++.h> using namespace std;
const int N = 1e5 + 10;
const int M = 1e9 + 7; int dp[1<<20][20]; vector<int> adj[20];
int main() { int n, m;cin >> n >> m;
for(int i = 0;i < m; ++i) { int u, v; cin >> u >> v; u--;v--; adj[v].push_back(u); }
dp[1][0] = 1;
for(int mask = 2; mask < (1<<n); mask++) { if(!(mask&1)) continue;
if((mask&(1<<(n-1)))&& mask != ((1<<n)-1)) continue;
for(int u = 0;u < n; ++u) { if(!(mask & (1<<u))) continue;
int prev = mask ^ (1 << u); for(int v : adj[u]) { if(prev & (1<<v)) { dp[mask][u] = (dp[mask][u] + dp[prev][v]) % M; } } } } cout << dp[(1<<n)-1][n-1] << endl;
}
|