题意:给定n个点和m条边,对于每个点来说与它相连的边要么是on,要么是off,求对于每个点来说,on=off的方案数。
思路:n最大是8,那么最多28条边,爆搜就可以,但是也需要剪枝一下,m是奇数或者某个点度数为奇数的情况下,没有满足条件的方案数,直接跳过。剩下的,爆搜每条边就可以。
#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
struct node
{
int x,y;
}a[105];
int d[105],n,m,ans,on[105],off[105];
void dfs(int cnt)
{
if(cnt==m)
{
for(int i=1;i<=n;i++)
if(on[i]!=off[i])
return;
ans++;
return;
}
int x=a[cnt].x,y=a[cnt].y;
if(on[x]<d[x]/2&&on[y]<d[y]/2)
{
on[x]++;on[y]++;
dfs(cnt+1);
on[x]--;on[y]--;
}
if(off[x]<d[x]/2&&off[y]<d[y]/2)
{
off[x]++;off[y]++;
dfs(cnt+1);
off[x]--;off[y]--;
}
}
int main()
{
int t;
cin>>t;
while(t--)
{
memset(d,0,sizeof d);
memset(on,0,sizeof on);
memset(off,0,sizeof off);
cin>>n>>m;
for(int i=0;i<m;i++)
{
int aa,bb;
scanf("%d%d",&aa,&bb);
d[aa]++;d[bb]++;
a[i]={aa,bb};
}
int flag=1;
for(int i=1;i<=n&&flag;i++)
if(d[i]&1) flag=0;
if((m&1)||!flag)
{
printf("0\n");continue;
}
ans=0;
dfs(0);
cout<<ans<<endl;
}
return 0;
}