[CF11D] A Simple Task - 状态压缩dp
Description
求简单无向图的环数。
Solution
钦定最小编号的点是每个环的起点,这样找环就变成了找环路
设 (f[s][i]) 表示遍历过的点集为 s,当前点为 i 的路径数
转移时判定一下状态的 Lowbit 和新点的关系即可
#include <bits/stdc++.h>
using namespace std;
#define int long long
const int N = 20;
const int S = 1 << N;
int n, m, f[S][N], ans, g[N][N];
int lowbit(int x)
{
return x & (-x);
}
signed main()
{
ios::sync_with_stdio(false);
cin >> n >> m;
for (int i = 1; i <= m; i++)
{
int u, v;
cin >> u >> v;
--u;
--v;
g[u][v] = g[v][u] = 1;
}
for (int i = 0; i < n; i++)
f[1 << i][i] = 1;
for (int i = 0; i < 1 << n; i++)
for (int j = 0; j < n; j++)
{
if (!f[i][j])
continue;
for (int k = 0; k < n; k++)
if (g[j][k] && lowbit(i) <= 1 << k)
{
if (i & 1 << k)
{
if (lowbit(i) == 1 << k)
ans += f[i][j];
}
else
{
f[i | 1 << k][k] += f[i][j];
}
}
}
cout << (ans - m) / 2 << endl;
}