推理可得终于结果为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;
}