状压dp找寻环的个数 Codeforces Beta Round #11 D

Posted 不知姓名的黑猫君

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了状压dp找寻环的个数 Codeforces Beta Round #11 D相关的知识,希望对你有一定的参考价值。

http://codeforces.com/problemset/problem/11/D

题目大意:给你n个点,m条边,找该图中有几个换

思路:定义dp[i][j]表示i是圈的集合,j表示该集合的终点,定义起点为这些走过的点里面最小的

 

//看看会不会爆int!数组会不会少了一维!
//取物问题一定要小心先手胜利的条件
#include <bits/stdc++.h>
using namespace std;
#define LL long long
#define ALL(a) a.begin(), a.end()
#define pb push_back
#define mk make_pair
#define fi first
#define se second
#define haha printf("haha\\n")
const int maxn = 19;
LL dp[1 << maxn][maxn + 5];
int a[maxn + 5][maxn + 5];
int n, m;

void get_min(int val, int &cnt, int &st){
    int pos = 0;
    while (val){
        if (val & 1) st = min(st, pos), cnt++;
        val >>= 1;
        pos++;
    }
}
///定义dp[i][j]表示i是圈的集合,j表示该集合的终点,定义起点为这些走过的点里面最小的
int main(){
    cin >> n >> m;
    for (int i = 1; i <= m; i++){
        int u, v; scanf("%d%d", &u, &v);
        u--, v--;
        a[u][v] = a[v][u] = 1;
    }
    LL ans = 0;
    for (int i = 0; i < n; i++) dp[1 << i][i] = 1;///初始化
    for (int i = 1; i < (1 << n); i++){
        int cnt = 0, st = n;
        get_min(i, cnt, st);
        for (int j = 0; j < n; j++){
            if (dp[i][j]){///目前集合为i,终点为j。而且根据放入集合的顺序,j必然是在i集合里面的
                if (a[st][j] && cnt >= 3){///放入集合的最终的终点一定得是在st的旁边。否则会将形不成环的放入ans中
                    ans += dp[i][j];
                }
                for (int k = st + 1; k < n; k++){///放入终点大于st的。根据定义st必然为最小的起点。
                    ///然后k<st的已经在更小的状态中全部都计算过了
                    if (a[j][k] && !(i & (1 << k))){
                        dp[i | (1 << k)][k] += dp[i][j];
                    }
                }
            }
        }
    }
    /*haha;
    for(int i = 0; i < n; i++){
        for (int j = 0; j < (1 << n); j++){
            printf("%lld ", dp[j][i]);
        }
        cout << endl;
    }*/
    cout << ans / 2 << endl;
    return 0;
}
View Code

 

以上是关于状压dp找寻环的个数 Codeforces Beta Round #11 D的主要内容,如果未能解决你的问题,请参考以下文章

codeforces 1215 E Marbles-----状压DP

Codeforces Round #302 (Div. 1) C - Remembering Strings 状压dp

Codeforces1598 F. RBS(状压dp,预处理)

Codeforces 580D-Kefa and Dishes(状压DP)

Codeforces 895C - Square Subsets

Codeforces 453B Little Pony and Harmony Chest:状压dp记录转移路径