1023 新集合 dfs

链接:https://ac.nowcoder.com/acm/contest/23156/1023
来源:牛客网

题目描述

集合 sss 中有整数 111 到 nnn,牛牛想从中挑几个整数组成一个新的集合。

现在牛妹给牛牛加了 mmm 个限制 ,每个限制包含两个整数 uuu 和 vvv ( u≠vu\neq vu=v),且 uuu 和 vvv 不能同时出现在新集合中 。

请问牛牛能组成的新集合多少种。

可以选 0 个数。

返回一个整数,即新集合的种类数。

示例1

输入

复制
3,2,[(1,2),(2,3)]

返回值

复制
5

说明

当 n = 3 时,共有 8 个子集,当加上限制 (1, 2), (2, 3) 后,合法的自己有 [], [1], [2], [3], [1, 3] 共 5 个 

备注:

第一个参数为 nnn。

第二个参数为 mmm 。

第三个参数为 mmm 对 (u, v) 。

1<n≤201≤m≤4001≤u,v≤n1 < n \leq 20 \quad 1\leq m \leq 400\quad 1 \leq u, v\leq n1<n201m4001u,vn

 

分析

1.就是有多少集合数量,那组合一遍就可以了

2.但是那时候对求排列其实有点不知道怎么下手。。。。我好菜。。其实就是每取一个数都是一个新的排列,然后从小到大逐个加入删除就行。

3.但是这里有一个不能在一起的数。那个时候想的是,把每个已经加到序列中的数的对应的数的vis 都弄成true。然后返回的时候把vis 变成false。但这样返回的时候可能会把对于前面也是这样的数删除

就是可能有条件重合的数。

4.看了题解才知道直接给每个数一个权值,表示这个数被多少个数讨厌,递归的时候再让这个讨厌值+1-1。

5.然后就到了经典的语法bug。vector<vector<int>> mp(30);老是报错

6.然后改成数组就过了。然后vector<int> mp[30] 也可以过。。。

 

/**
 * struct Point {
 *    int x;
 *    int y;
 *    Point(int xx, int yy) : x(xx), y(yy) {}
 * };
 */

class Solution {
public:
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     *
     * @param n int 集合大小
     * @param m int 限制数量
     * @param limit Pointvector 不能同时出现的(u,v)集合
     * @return int
     */
    //基本状态压缩吧
    public:
    int N = 30;
    int vis[30];
    vector<int> mp[30];//这样就可以了???
    int nn = 0;
    int sum = 0;
    int ms[30][30];
    void dfs(int start) {
        sum ++ ;
        for(int i = start;i<=nn;i++) {
            if(!vis[i]) {
                vis[i] ++ ;
                for(int k = i + 1;k<=nn;k++) {if(find(mp[i].begin(),mp[i].end(),k) != mp[i].end()) {vis[k] ++ ;} }
//                 for(int k = i + 1;k<=nn;k++){ if(ms[i][k] == 1) {vis[k] ++ ;} }
                dfs(i + 1);
//                 for(int k = i + 1;k<=nn;k++) {if(ms[i][k] == 1) {vis[k] -- ;} }
                for(int k = i + 1;k<=nn;k++) {if(find(mp[i].begin(),mp[i].end(),k) != mp[i].end()) {vis[k] -- ;} }
                
                vis[i] -- ;
            }
        }
        
    }
    
    int solve(int n, int m, vector<Point>& limit) {
        // write code here
        nn = n;
        for(int i = 0;i<m;i++) {
            int x = limit[i].x,y = limit[i].y;
//             ms[x][y] = 1,ms[y][x] = 1;
            mp[x].push_back(y),mp[y].push_back(x);
        }
        dfs(1);
        return sum;
    }
};

posted @ 2022-07-02 22:40  er007  阅读(36)  评论(0编辑  收藏  举报