HDU 5305 Friends(dfs)

Description
一些朋友关系可离线可在线,要求每个人的离线朋友数等于在线朋友数,输出可能情况数
Input
多组用例,第一行为用例组数,每组用例第一行为两个整数n和m分别表示人数和关系数,之后m行每行两个整数a和b表示a和b有朋友关系
Output
对于每组用例,输出满足条件的可能情况数
Sample Input
2
3 3
1 2
2 3
3 1
4 4
1 2
2 3
3 4
4 1
Sample Output
0
2
Solution
直接爆搜,记录每个点的度数,奇数的直接不可能,偶数的分成两个数组,n1[i]表示i的在线朋友数,n2[i]表示i的离线朋友数,然后一条边一条边搜就行了,注意一个剪枝,当一条边的两个端点有一个n值为0,则return ;
Code

#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std;
struct node
{
    int u,v;
}e[50];
int n,m,ans;
int n1[10],n2[10],num[10];
void dfs(int x)
{
    if(x==m+1)
    {
        ans++;
        return ;
    }
    int u=e[x].u;
    int v=e[x].v;
    if(n1[u]&&n1[v])
    {
        n1[u]--;
        n1[v]--;
        dfs(x+1);
        n1[u]++;
        n1[v]++;
    }
    if(n2[u]&&n2[v])
    {
        n2[u]--;
        n2[v]--;
        dfs(x+1);
        n2[u]++;
        n2[v]++;
    }
    return ;
}
int main()
{
    int T;
    cin>>T;
    while(T--)
    {
        ans=0;
        memset(e,0,sizeof(e));
        memset(n1,0,sizeof(n1));
        memset(n2,0,sizeof(n2));
        memset(num,0,sizeof(num));
        cin>>n>>m;
        for(int i=1;i<=m;i++)
        {
            scanf("%d%d",&e[i].u,&e[i].v);
            num[e[i].u]++;
            num[e[i].v]++;
        }
        int flag=1;
        for(int i=1;i<=n;i++)
        {
            n1[i]=n2[i]=num[i]/2;
            if(num[i]%2)
            {
                flag=0;
                break;
            }
        }
        if(!flag)
        {
            printf("0\n");
            continue;
        }
        dfs(1);
        printf("%d\n",ans);
    }
    return 0;
}

你可能感兴趣的:(HDU 5305 Friends(dfs))