Codeforces Round #254 (Div. 2) B (445B)DZY Loves Chemistry


推理可得终于结果为2的(n-可分组合数)次方。

问题是怎么求出可分组合数,深搜就可以,当然并查集也能够。


AC代码例如以下:

深搜代码!!!

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#define M 100005
#define ll long long
using namespace std;

int a,b,c[205][205],vis[205];
int n,m;

void dfs(int x)
{
    int i;
    vis[x]=1;
    for(i=1;i<=n;i++)
    {
        if(!vis[i]&&c[x][i])
            dfs(i);
    }
}

int main()
{

    int i,j;
    int sum,ans=0;
    cin>>n>>m;
    memset(c,0,sizeof c);
    memset(vis,0,sizeof vis);
    for(i=0;i<m;i++)
        {
            cin>>a>>b;
            c[a][b]=1;
            c[b][a]=1;//将a,b关联,能够用容器。但我认为不是必需
        }
    if(m==0)
        cout<<"1"<<endl;
    else{
        for(j=1;j<=n;j++)
        {
            if(!vis[j])
            {dfs(j);ans++;}//从一点搜起。记录组合数
        }
        cout<<(1LL<<(n-ans))<<endl;
    }

    return 0;
}

并查集代码!!





#include<stdio.h>
#include<string.h>
#include<iostream>
using namespace std;

int f[50005],vis[50005];
int find (int x)
{
    if(f[x]==x)
        return f[x];
    else return find(f[x]);
}

int main()
{
    int n,m;
    int i,j;
    int a,b,c;

    long long ans;
    cin>>n>>m;
        memset(vis,0,sizeof vis);
        ans=0;
        for(i=1;i<=n;i++)
            f[i]=i;
        for(i=1;i<=m;i++)
        {
            cin>>a>>b;
            a=find (a);
            b=find (b);
            f[a]=b;
        }
        for(i=1;i<=n;i++)
        {
            c=find(i);
            if(!vis[c])
            {ans++;vis[c]=1;}
        }
        cout<<(1LL<<(n-ans))<<endl;
    return 0;
}




原文地址:https://www.cnblogs.com/yjbjingcha/p/6845150.html