題目鏈接:http://acm.hdu.edu.cn/showproblem.php?pid=5305
題意:給你n個人,m條關係,關係可以是online也可以是offline,讓你求在保證所有人online關係的朋友和offline關係的朋友相等的情況下,這樣的情況有多少種。
思路:因爲online關係和offline關係的人數相等,而且m最多才28,所以只要枚舉每個人的一半的關係是否符合要求即可,而且根據題意m是奇數或者有一個人的總關係爲奇數那麼就沒有符合要求的情況,這樣可以排除很多情況。
代碼:
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <cstring>
#include <iostream>
#include <queue>
#include <algorithm>
#include <vector>
using namespace std;
#define LL __int64
int f[10],on[10],off[10];
int m,n;
struct node
{
int x,y;
}nn[30];
void init()
{
memset(f,0,sizeof(f));
memset(on,0,sizeof(on));
memset(off,0,sizeof(off));
}
int dfs(int cot)
{
int x,y,i,ans;
ans=0;
if(cot>=m)
{
for(i=1;i<=n;i++)
{
if(on[i]!=off[i])
return 0;
}
return 1;
}
x=nn[cot].x;
y=nn[cot].y;
if(on[x]<f[x]/2&&on[y]<f[y]/2)
{
on[x]++;
on[y]++;
ans+=dfs(cot+1);
on[x]--;
on[y]--;
}
if(off[x]<f[x]/2&&off[y]<f[y]/2)
{
off[x]++;
off[y]++;
ans+=dfs(cot+1);
off[x]--;
off[y]--;
}
return ans;
}
int main()
{
int i,T,ans;
while(~scanf("%d",&T))
{
while(T--)
{
scanf("%d%d",&n,&m);
init();
for(i=0;i<m;i++)
{
scanf("%d%d",&nn[i].x,&nn[i].y);
f[nn[i].x]++;
f[nn[i].y]++;
}
if(m&1)
{
printf("0\n");
continue;
}
int flag=0;
for(i=1;i<=n;i++)
{
if(f[i]&1)
{
flag=1;
break;
}
}
if(flag)
{
printf("0\n");
continue;
}
ans=dfs(0);
printf("%d\n",ans);
}
}
return 0;
}