题目的意思是要求我感觉有一些不好理解,你可以将其等价成我下面的的含义
给出遮个点遭条边逨n ≤ 逸逩,每个边可能是黑色也可能是白色,求每个点相连的边黑边和白边的数量 都相等的图有几种。
这道题目的数量级比较小因此可以用爆搜一下,当然也有其他的方法--状压,这里我先用dfs
#include<bits/stdc++.h>
using namespace std;
#define rep(i,a,b) for(int i=a;i<=b;i++)
#define pre(i,a,b) for(int i=a;i>=b;i--)
int on[100];//存储i顶点的online边
int vis[10][10];
int off[100];//i顶点的offonline边
int w[100];//用来存每个点所能连接的边的个数
int n,m;
int ans=0;
struct node
{
int v;
int u;
}num[100];
void dfs(int step)
{
if(step==m)
{
ans++;
return ;
}
int x=num[step+1].u;//开始枚举题目所给的顶点,可以为online边也可为offline
int y=num[step+1].v;//不会它在上一组数据是12为online时下一次如果offline没用过的话就将
if(on[x]&&on[y])//12又变成offonline的,因为是按输入的数据来枚举的,每一条边最多出现一次
{
on[x]--,on[y]--;
dfs(step+1);
on[x]++,on[y]++;
}
if(off[x]&&off[y])
{
off[x]--,off[y]--;
dfs(step+1);
off[x]++,off[y]++;
}
//return ;
}
int main(){
int T;
cin>>T;
while(T--){
cin>>n>>m;
memset(on,0,sizeof(on));
memset(off,0,sizeof(off));
memset(w,0,sizeof(w));
ans=0;
rep(i,1,m)
{
cin>>num[i].v>>num[i].u;
// if(num[i].v>num[i])
// swap(num[i].v,num[i].u);
w[num[i].v]++;
w[num[i].u]++;
}
bool f=0;
rep(i,1,n)
if(w[i]&1)//如果有一个顶点的边数是奇数,那肯定是不符合题意的,就直接输出0
{
f=1;
break;
}
if(f)
cout<<0<<endl;
else
{
rep(i,1,n)
{
on[i]=off[i]=w[i]/2;//将所得的总共的边数除以2,就是online与offonline的个数
}
dfs(0),cout<<ans<<endl;
}
}
return 0;
}