分析:给你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; }