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