[CF11D] A Simple Task

[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;
}
原文地址:https://www.cnblogs.com/mollnn/p/14362871.html