hdu 5305 Friends(2015多校第二场第6题)记忆化搜索
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5305
题意:给你n个人,m条关系,关系可以是online也可以是offline,让你求在保证所有人online关系的朋友和offline关系的朋友相等的情况下,这样的情况有多少种。
思路:因为online关系和offline关系的人数相等,而且m最多才28,所以只要枚举每个人的一半的关系是否符合要求即可,而且根据题意m是奇数或者有一个人的总关系为奇数那么就没有符合要求的情况,这样可以排除很多情况。
代码:
1 #include <cstdio> 2 #include <cstdlib> 3 #include <cmath> 4 #include <cstring> 5 #include <iostream> 6 #include <queue> 7 #include <algorithm> 8 #include <vector> 9 using namespace std; 10 #define LL __int64 11 12 int f[10],on[10],off[10]; 13 int m,n; 14 struct node 15 { 16 int x,y; 17 }nn[30]; 18 void init() 19 { 20 memset(f,0,sizeof(f)); 21 memset(on,0,sizeof(on)); 22 memset(off,0,sizeof(off)); 23 } 24 int dfs(int cot) 25 { 26 int x,y,i,ans; 27 ans=0; 28 if(cot>=m) 29 { 30 for(i=1;i<=n;i++) 31 { 32 if(on[i]!=off[i]) 33 return 0; 34 } 35 return 1; 36 } 37 x=nn[cot].x; 38 y=nn[cot].y; 39 if(on[x]<f[x]/2&&on[y]<f[y]/2) 40 { 41 on[x]++; 42 on[y]++; 43 ans+=dfs(cot+1); 44 on[x]--; 45 on[y]--; 46 } 47 if(off[x]<f[x]/2&&off[y]<f[y]/2) 48 { 49 off[x]++; 50 off[y]++; 51 ans+=dfs(cot+1); 52 off[x]--; 53 off[y]--; 54 } 55 return ans; 56 } 57 58 int main() 59 { 60 int i,T,ans; 61 while(~scanf("%d",&T)) 62 { 63 while(T--) 64 { 65 scanf("%d%d",&n,&m); 66 init(); 67 for(i=0;i<m;i++) 68 { 69 scanf("%d%d",&nn[i].x,&nn[i].y); 70 f[nn[i].x]++; 71 f[nn[i].y]++; 72 } 73 if(m&1) 74 { 75 printf("0\n"); 76 continue; 77 } 78 int flag=0; 79 for(i=1;i<=n;i++) 80 { 81 if(f[i]&1) 82 { 83 flag=1; 84 break; 85 } 86 } 87 if(flag) 88 { 89 printf("0\n"); 90 continue; 91 } 92 ans=dfs(0); 93 printf("%d\n",ans); 94 } 95 } 96 return 0; 97 }