hdu 5305 Friends(2015多校第二场第6题)记忆化搜索

来源:互联网 发布:领导力的文书 知乎 编辑:程序博客网 时间:2024/06/05 15:58

题目链接: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 __int64int 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;}


0 0
原创粉丝点击