HDU 5305 Friends(dfs)

Friends

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)

Total Submission(s): 297    Accepted Submission(s): 127

Problem Description

There are n people
and m pairs
of friends. For every pair of friends, they can choose to become online friends (communicating using online applications) or offline friends (mostly using face-to-face communication). However, everyone in these n people
wants to have the same number of online and offline friends (i.e. If one person has x onine
friends, he or she must have x offline
friends too, but different people can have different number of online or offline friends). Please determine how many ways there are to satisfy their requirements.

Input

The first line of the input is a single integer T (T=100),
indicating the number of testcases.

For each testcase, the first line contains two integers n (1≤n≤8) and m (0≤m≤n(n?1)2),
indicating the number of people and the number of pairs of friends, respectively. Each of the next m lines
contains two numbers x and y,
which mean x and y are
friends. It is guaranteed that x≠y and
every friend relationship will appear at most once.

Output

For each testcase, print one number indicating the answer.

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

Source

/*

题意:n个人,m个关系,每个人和别人的关喜有线上和线下,求每个人线上和线下的关系一样多的方案数
思路: dfs
先贴别人代码,跑的快
,我的跑的慢

*/

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<queue>
#include<stack>
#include<vector>
#include<set>
#include<map>

#define L(x) (x<<1)
#define R(x) (x<<1|1)
#define MID(x,y) ((x+y)>>1)

#define eps 1e-8
using namespace std;

typedef __int64 LL;

#define N 100

int x[N],y[N],in[N],on[N],off[N];
int n,m;
int ans;

bool judge()
{
    if(m&1) return false;
    for(int i=1;i<=n;i++) if(in[i]&1) return false;
    return true;
}

void dfs(int pos)
{
    if(pos==m)
    {
        ans++;
        return ;
    }
    int u=x[pos],v=y[pos];
    if(on[u]<in[u]/2&&on[v]<in[v]/2)  //这个边为online 边
    {
        on[u]++;
        on[v]++;
        dfs(pos+1);
        on[u]--;
        on[v]--;
    }

    if(off[u]<in[u]/2&&off[v]<in[v]/2) //这个边为off边
    {
        off[u]++;
        off[v]++;
        dfs(pos+1);
        off[u]--;
        off[v]--;
    }
}
int main()
{
    int i,j,t;
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d%d",&n,&m);
        memset(in,0,sizeof(in));
        memset(on,0,sizeof(on));
        memset(off,0,sizeof(off));

        for(i=0;i<m;i++)
        {
            scanf("%d%d",&x[i],&y[i]);
            in[x[i]]++;
            in[y[i]]++;
        }
        ans=0;
        if(!judge())
        {
            printf("0\n");
            continue;
        }
        dfs(0);
        printf("%d\n",ans);
    }
    return 0;
}
/*
我的代码
*/
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<queue>
#include<stack>
#include<vector>
#include<set>
#include<map>

#define L(x) (x<<1)
#define R(x) (x<<1|1)
#define MID(x,y) ((x+y)>>1)

#define bug printf("hihi\n")

#define eps 1e-8
typedef __int64 ll;

using namespace std;

#define INF 0x3f3f3f3f

#define N 1<<8

__int64 ans;

int on[N],down[N];
int n,m,f[N],in[N];

inline int get(int x)
{
    int s=0;
    while(x)
    {
        s++;
        x&=(x-1);
    }
    return s;
}

inline bool judge(int pos,int cur)
{
    int i;
    for(i=0;i<n;i++)
       if(on[i]&(1<<pos)&&!(cur&(1<<i))) return false;

    for(i=0;i<n;i++)
      if(down[i]&(1<<pos)&&(cur&(1<<i))) return false;
    return true;
}

void dfs(int pos)
{
    if(pos==n)
    {
        ans++;
        return ;
    }
    int i,len=1<<n;
    for(i=0;i<len;i++)
    {
        if((f[pos]&i)!=i) continue;
        int tt=get(i);
        if(tt!=in[pos]/2) continue;
        if(!judge(pos,i)) continue;
        on[pos]=i;
        down[pos]=f[pos]^i;
        dfs(pos+1);
        on[pos]=0;
        down[pos]=0;
    }
}

int main()
{
    int i,j,t;
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d%d",&n,&m);
        int u,v;
        memset(f,0,sizeof(f));
        memset(on,0,sizeof(on));
        memset(down,0,sizeof(down));
        memset(in,0,sizeof(in));
        bool flag=false;
        if(m&1) flag=true;
        while(m--)
        {
            scanf("%d%d",&u,&v);
            u--;v--;
            f[u]|=1<<v;
            f[v]|=1<<u;
            in[u]++;
            in[v]++;
        }

        for(i=0;i<n;i++)
        {
            if(in[i]&1) flag=true;
        }
        if(flag)
        {
            printf("0\n");
            continue;
        }
        ans=0;
        int len=1<<n;
        for(i=0;i<len;i++)
        {
            if((f[0]&i)!=i) continue;
            int tt=get(i);
            if(tt!=in[0]/2) continue;
            on[0]=i;
            down[0]=f[0]^i;
            dfs(1);
            on[0]=0;
            down[0]=0;
        }
        printf("%I64d\n",ans);
    }
    return 0;
}

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-08-02 07:00:27

HDU 5305 Friends(dfs)的相关文章

hdu 5167 Fibonacci(DFS)

hdu 5167 Fibonacci 问题描述 斐波那契数列的递归定义如下: Fi=???01Fi?1+Fi?2i = 0i = 1i > 1 现在我们需要判断一个数是否能表示为斐波那契数列中的数的乘积. 输入描述 有多组数据,第一行为数据组数T(T≤100,000). 对于每组数据有一个整数n,表示要判断的数字. 0≤n≤1,000,000,000 输出描述 对于每组数据,如果可以输出"Yes",否则输出"No". 输入样例 3 4 17 233 输出样例

HDU 3158 PropBot(DFS)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3158 Problem Description You have been selected to write the navigation module for PropBot. Unfortunately, the mechanical engineers have not provided a lot of flexibility in movement; indeed, the PropBot

Hdu 1175 连连看(DFS)

Problem地址:http://acm.hdu.edu.cn/showproblem.php?pid=1175 因为题目只问能不能搜到,没问最少要几个弯才能搜到,所以我采取了DFS. 因为与Hdu 1728相比,都要考虑转弯次数,所以在判断转弯的次数上,两者可以相互借鉴. 这一点应该不难想到,在搜索前就应判断两点的值是否相等,以及两点的值中是否有0.如果不相等或其中一值为0,则可以判断是"NO". 时间虽是10000ms,但只是这样,还是超时. 后来又加了一个数组walk[][],用

hdu 1501 Zipper (dfs+记忆化搜索)

Zipper Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 6491    Accepted Submission(s): 2341 Problem Description Given three strings, you are to determine whether the third string can be formed

hdu 1518 Square (dfs搜索可参考poj1011)

Square Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 8589    Accepted Submission(s): 2784 Problem Description Given a set of sticks of various lengths, is it possible to join them end-to-end

hdu 1016 Prime Ring Problem (dfs)

一切见注释. #include <cstdio> #include <iostream> #include <cstring> #include <algorithm> using namespace std; bool vis[22]; int n; int ans[22]; int top; bool isprime(int x)//判断素数 { for(int i=2;i<x;i++) if(x%i==0)return false; return

HDU 2209 翻纸牌游戏(dfs)

翻纸牌游戏 Time Limit: 9000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 2180    Accepted Submission(s): 787 Problem Description 有一种纸牌游戏,很有意思,给你N张纸牌,一字排开,纸牌有正反两面,开始的纸牌可能是一种乱的状态(有些朝正,有些朝反),现在你需要整理这些纸牌.但是麻烦的是,每当你翻一张

HDU 1455——Sticks(神棍)

这题跟 HDU1518差不多 附上测试数据~~ 64 40 40 30 35 35 26 15 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 43 42 42 41 10 4 40 40 40 40 40 40 40 40 40 40 40 40 40 40 25 39 46 40 10 4 40 40 37 18 17 16 15 40 40 40 40 40 40 40 40 46 40 37 32 10 47 4 42 56 61 23 5

POJ 3087 Shuffle&#39;m Up (DFS)

题目链接:Shuffle'm Up 题意:有a和b两个长度为n的字符序列,现定义操作: 将a.b的字符交叉合并到一个序列c,再将c最上面的n个归为a,最下面n个归为b 给出a,b和目标序列c,问最少多少次操作a.b转化为c 解析:将a.b放入哈希表,然后模拟操作过程直接dfs即可. AC代码: #include <cstdio> #include <iostream> #include <cstring> #include <map> using names