ABC 289 C - Coverage(dfs)

半个多月没写题,连暴力dfs都忘记了,完蛋,烂菜地里了

https://atcoder.jp/contests/abc289/tasks/abc289_c

题目大意:

给定一个N,M个集合,然后分别给出M个集合里面的数字个数以及每个数,

问我们怎样选集合能达到1到N的每一个数字都存在,问我们这样的选法有多少种?求出方法数。
Sample Input 1  
3 3
2
1 2
2
1 3
1
2
Sample Output 1  
3

笑迷糊了,一开始范围都没看到,想半天。做题先看数据范围
N,M的范围都在10以内,所以只管妥妥暴力dfs,每个集合都进行选和不选即可。

#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef pair<LL,LL> PII;
const LL MAXN=1e18,MINN=31;
const LL N=1e6+10,M=4010;
const double PI=3.1415926535;
#define endl '\n'
vector<vector<LL>> a(N);
LL m,n,ans=0;
bool vis[N];
void dfs(LL idx)
{
    if(idx>n)
    {
        set<LL> st;
        for(int i=1;i<=n;i++)
        {
            if(vis[i])
            {
                for(int j=0;j<a[i].size();j++)
                    st.insert(a[i][j]);
            }
        }
        if(st.size()==m) ans++;
        return ;
    }
    //选
    vis[idx]=true;
    dfs(idx+1);
    //不选
    vis[idx]=false;
    dfs(idx+1);
}
int main()
{
    cin.tie(0); cout.tie(0); ios::sync_with_stdio(false);
    int T=1;
    //cin>>T;
    while(T--)
    {
        cin>>m>>n;
        for(int i=1;i<=n;i++)
        {
            LL t;
            cin>>t;
            for(int j=1;j<=t;j++)
            {
                LL x;
                cin>>x;
                a[i].push_back(x);
            }
        }
        dfs(1);
        cout<<ans<<endl;
    }
    return 0;
}
posted @ 2023-02-23 20:43  高尔赛凡尔娟  阅读(23)  评论(0编辑  收藏  举报