分析:给你n个人,和m个朋友关系,让你求满足每个人的线上和线下的朋友数相等的方案有多少种。如果有一个人的朋友数为奇数,不存在可行解,输出0,否则令每个人未确认的线上朋友on[i]和线下朋友off[i]的个数相等都为du[i]/2,然后从第一条边开始Dfs搜索,如果第num条的连的两个点都有未确认的线上朋友,则确认顶点u,v为线上朋友,所以未确认的on[u]--,on[v]--然后继续搜索下一条边,然后恢复他们为未确认的状态on[u]++,on[v]++,判断两个人能否成为下线朋友,如果能搜索到m+1条边就能说明确认了所有m条边是线上还是线下朋友;如果其中一个的未确认线上朋友数为0,那么u,v就不可能成为线上朋友,线下off同理。
# include <stdio.h>
# include <string.h>
typedef struct edge
{
int u,v;
}Edge;
Edge e[30];
int n,m,ans,du[10],on[10],off[10];
void Dfs(int num)
{
int u=e[num].u,v=e[num].v;
if(num>m)
{
ans++;
return;
}
if(on[u]&&on[v])
{
on[u]--;
on[v]--;
Dfs(num+1);
on[u]++;
on[v]++;
}
if(off[u]&&off[v])
{
off[u]--;
off[v]--;
Dfs(num+1);
off[u]++;
off[v]++;
}
}
int main()
{
int i,t;
scanf("%d",&t);
while(t--)
{
scanf("%d%d",&n,&m);
memset(du,0,sizeof(du));
for(i=1;i<=m;i++)
{
scanf("%d%d",&e[i].u,&e[i].v);
du[e[i].u]++;
du[e[i].v]++;
}
for(i=1;i<=n;i++)
{
on[i]=off[i]=du[i]/2;
if(du[i]&1)
break;
}
if(i<=n)
printf("0\n");
else
{
ans=0;Dfs(1);
printf("%d\n",ans);
}
}
return 0;
}