HDU 5305 Friends (深搜)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5305

题面:

Friends

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

Total Submission(s): 1149    Accepted Submission(s): 569

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

2015 Multi-University Training Contest 2

解题:

因为28本来就不大,很容易想到搜索,但是直接搜是会超时的,加一个当一个人的现实或者虚拟好友数大于其本身关系数一半时,就返回的剪枝即可。注意开始可以直接判一个人关系数为奇,那么就不比进行搜索了。

代码:

#include <iostream>
#include <cstdio>
#include <queue>
#include <cstring>
using namespace std;
int t,n,m,cnt_net[10],cnt_real[10],cnt_all[10],a,b,ans,fm[40],to[40];
void dfs(int No,bool status)
{
  a=fm[No];
  b=to[No];
  if(status)
  {
    cnt_real[a]++;
    cnt_real[b]++;
    if((cnt_real[a]>cnt_all[a]/2)||(cnt_real[b]>cnt_all[b]/2))
        return;
  }
  else
  {
    cnt_net[a]++;
    cnt_net[b]++;
    if((cnt_net[a]>cnt_all[a]/2)||(cnt_net[b]>cnt_all[b]/2))
        return;
  }
  if(No==m)
  {
      bool sign=true;
      for(int i=1;i<=n;i++)
      {
          if(cnt_real[i]!=cnt_net[i])
          {
              sign=false;
              break;
          }
      }
      if(sign)ans++;
      return;
  }
  dfs(No+1,1);
  cnt_real[fm[No+1]]--;
  cnt_real[to[No+1]]--;
  dfs(No+1,0);
  cnt_net[fm[No+1]]--;
  cnt_net[to[No+1]]--;
}
int main()
{
    scanf("%d",&t);
    while(t--)
    {
      bool flag=true;
      ans=0;
      scanf("%d%d",&n,&m);
      memset(cnt_net,0,sizeof(cnt_net));
      memset(cnt_real,0,sizeof(cnt_real));
      memset(cnt_all,0,sizeof(cnt_all));
      for(int i=1;i<=m;i++)
      {
        scanf("%d%d",&a,&b);
        fm[i]=a;
        to[i]=b;
        cnt_all[a]++;
        cnt_all[b]++;
      }
      for(int i=1;i<=n;i++)
      {
          if(cnt_all[i]%2)
          {
              flag=false;
              break;
          }
      }
      if(!flag)
      {
          printf("0\n");
          continue;
      }
      if(m)
      {
          dfs(1,0);
        cnt_net[fm[1]]--;
        cnt_net[to[1]]--;
    //    cout<<cnt_net[fm[1]]<<" "<<cnt_net[to[1]]<<endl;
        dfs(1,1);
      }
      else ans=1;
      printf("%d\n",ans);
    }
    return 0;
}

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

时间: 2024-11-05 14:45:50

HDU 5305 Friends (深搜)的相关文章

HDU 5305 Friends(深搜)

题意:t组数据,每组一个n和m表示点数和边数,接下来m条边,每条边两种状态,求每个点邻接边的两种状态数目相同的排列方式有几种 分析:从第一个顶点开始往下深搜每条边,每条边两种状态,注意回朔. 代码: #include<cstdio> #include<cstring> #include<algorithm> #include<cmath> using namespace std; const int maxn = 10; int n,m,ans; int e

hdu 1518 Square 深搜,,,,花样剪枝啊!!!

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

hdu 5706 GirlCat(深搜)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5706 --报考杭州电子科技大学! GirlCat Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 132    Accepted Submission(s): 104 Problem Description As a cute girl,

HDU 2614 Beat 深搜DFS

这道题目还是比较水的,但是题意理解确实费了半天劲,没办法 谁让自己是英渣呢! 题目大意: 猪脚要解决问题, 他有个习惯,每次只解决比之前解决过的问题的难度要大. 他给我们一个矩阵  矩阵的 i 行 j 列表示 解决完第 i 个问题后再解决第 j 个问题 花费时间为 T[i][j] 也就是 题目的难度. 并且他是从第0个问题开始解决的,第0个问题花费的时间为 0 下面是代码 : 1 #include<stdio.h> 2 #include<stdlib.h> 3 #include&l

HDU 6264 (深搜,数论)

题目链接 题意 求\(\sum_{d|n}\phi (d) \times {n\over d}\),其中\(\phi(n) = n\prod_{p|n}({1-{1\over p}})\) 分析 将\(\phi(d)\) 分解式子代入可知:\(\sum_{d|n}(n\times \prod_{p|d}(1-{1\over p}))\) \(d\) 是 \(n\) 的因子,枚举 \(d\) 的质因子的所有可能的组成情况共\(2^c\)中. 其中 c 为 n 的不同质因子个数(即题目中输入的 n

深搜基础题目 杭电 HDU 1241

HDU 1241 是深搜算法的入门题目,递归实现. 原题目传送门: http://acm.hdu.edu.cn/showproblem.php?pid=1241 代码仅供参考,c++实现: #include <iostream> using namespace std; char land[150][150]; int p,q; void dfs(int x,int y){ land[x][y] = '*'; if(land[x-1][y]!= '@' && land[x+1]

【深搜加剪枝五】HDU 1010 Tempter of the Bone

Tempter of the BoneTime Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 64326    Accepted Submission(s): 17567 Problem Description The doggie found a bone in an ancient maze, which fascinated him a l

hdu 1175 连连看 (深搜)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1175 题目大意:如果某两个相同的棋子,可以通过一条线连起来(这条线不能经过其它棋子)这样的两个棋子可以消掉.还有一个要注意的地方的就是转弯.转弯的次数不超过两次,这两个棋子才可以在棋盘上消去~ 1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 using namespace std; 5 int

hdu 1518 Square(深搜dfs)

转载请注明出处:http://blog.csdn.net/u012860063?viewmode=contents 题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1518 --------------------------------------------------------------------------------------------------------------------------------------------

hdu 1518 Square(深搜+剪枝)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1518 题目大意:根据题目所给的几条边,来判断是否能构成正方形,一个很好的深搜应用,注意剪枝,以防超时! 1 #include <iostream> 2 #include <cstdio> 3 #include<algorithm> 4 #include <cstring> 5 using namespace std; 6 int ap[30],visit[30]