HDU 5301 Friends(DFS + 枚举)

来源:互联网 发布:大数据与中国发展 编辑:程序博客网 时间:2024/06/07 06:45

Friends

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 1192    Accepted Submission(s): 595


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 (1n8) and m (0mn(n1)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 xy and every friend relationship will appear at most once. 
 

Output
For each testcase, print one number indicating the answer.
 

Sample Input
23 31 22 33 14 41 22 33 44 1
 

Sample Output
02
 
题目大意:有n个人,分别有各自的朋友,每个人与他的朋友的关系分为线上朋友和线下朋友,现在要求每个人的朋友中线上朋友的数目与线下朋友的数目相等,问有多少种方案?





解题思路:根据题目描述,(1<=n<=8,0<=m<=n*(n-1)/2)数据范围比较小,可以暴力枚举每一种方案。枚举m对关系分别为线上朋友和线下朋友,对每一种方式,判断是否满足对每个人都有线上朋友等于线下朋友,满足则方案数加1,不满足则方案数不处理。对n个人建立一个n*n的图ed[n][n],并且初始化所有的值为0,如果第i个人和第j个人是朋友,则ed[i][j]和ed[j][i]的值赋为1;然后从(1,2)开始DFS深度搜索,如果搜索到最后,满足条件则方案数加1,否则不加。
例如:有5个人,10对关系为12,13,14,15,23,24,25,34,35,45
建图:
    1   2   3   4   5
1  0   1   1   1   1
2  1   0   1   1   1
3  1   1   0   1   1 
4  1   1   1   0   1 
5  1   1   1   1   0

DFS深度搜索枚举12(线上或线下),13(线上或线下),14(线上或线下),15(线上或线下),23(线上或线下),24(线上或线下),25(线上或线下),34(线上或线下),35(线上或线下),45(线上或线下)的关系(du[ ]初始状态为0,如果定义线上关系时,du[ ]++,那么线下关系时,du[ ]--)。对每一种方案做判断。


代码如下:
#include <cstdio>#include <cstdlib>#include <cstring>#include <cmath>#include <ctime>#include <iostream>#include <algorithm>#include <string>#include <vector>#include <deque>#include <list>#include <set>#include <map>#include <stack>#include <queue>#include <numeric>#include <iomanip>#include <bitset>#include <sstream>#include <fstream>#include <limits.h>#define debug "output for debug\n"#define pi (acos(-1.0))#define eps (1e-4)#define inf (1<<28)#define sqr(x) (x) * (x)using namespace std;typedef long long ll;typedef unsigned long long ULL;//du[]的值表示初始,线上和线下的状态int T, n, m, a, b, ans, du[10];//ed[i][j]的值表示第i个人与第j个人是否有朋友关系int ed[10][10];//深度搜索计算方案总数//这里搜索的方式是按x由小到大,如果x相同,按y由小到大void dfs(int x, int y){if (x > n)//当从起点到达终点时,说明该方案是满足条件的     ans++;else if (y > n)//当某个人(即第x个人)的所有朋友关系都假设完后,判断是否满足条件(线上=线下)    {if (du[x])//满足条件(线上=线下)的判定条件(du[x]==0)    return ;//不满足,该方案不可行,换另一种方案dfs(x + 1, x + 2);//满足,判定下一个人}else{if (ed[x][y])//第x个人和第y个人是朋友关系{    //假设第x个人和第y个人是线上朋友关系du[x]++;//du[y]++;//dfs(x, y + 1);//使du[x],du[y]恢复到初始状态(值为0)du[x]--;du[y]--;//假设第x个人和第y个人是线下朋友关系du[x]--;du[y]--;dfs(x, y + 1);//使du[x],du[y]恢复到初始状态(值为0)du[x]++;du[y]++;}else//第x个人和第y个人不是朋友关系,搜索下一个            dfs(x, y + 1);}}int main(){scanf("%d", &T);while (T--)    {scanf("%d%d", &n, &m);//初始化for (int i = 1; i <= n; i++)for (int j = 1; j <= n; j++)ed[i][j] = 0;        //建图while (m--){scanf("%d%d", &a, &b);ed[a][b] = ed[b][a] = 1;}ans = 0;//深度搜索dfs(1, 2);printf("%d\n", ans);}}

0 0