Friends
题目描述:
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:
Sample Output:
题目大意:
给出了T个测试样例子,给了n个人,m对朋友,他要求每一个人都拥有同等数量的在线朋友与离线朋友,要求在m对朋友来分配,有多少种方式,意思就是说这里有m对朋友,但他们没有标明是在线还是离线,所以由你来标明,分配即可。
思路分析:
这道题首先要看每个人拥有多少个朋友,如果该朋友数量是奇数,说明无法同等分配,如果是偶数才能继续分配,这里有个很简单的思路把,就是朋友的数量是固定的,但分配朋友对的数量的时候,在线朋友对多一个,离线朋友对就少一个,那么依次为条件DFS,看是否所有朋友对数量,能否等于m就即可,就多出一种方法。
AC代码:
用时:15ms
#include<cstdio>
#include<iostream>
#include<string.h>
using namespace std;
int num[10000];//记录该人有多少朋友
int Leave[10000];//在线人数
int rise[10000];//离线人数
int sum,flag;//flag用于标记,sum用于方法
int m,n;
struct
{
int n1,n2;
}Lemon[10000];//标记朋友对数量
void LemonDFS(int num1)
{
if(num1 == m+1)//如果刚好等于朋友对数量,说明满足条件
{
sum++;
return;
}
//记录朋友对的关系
int LF= Lemon[num1].n1;
int RF= Lemon[num1].n2;
if(rise[LF] && rise[RF])//在线人数分配
{
rise[LF]--;
rise[RF]--;
LemonDFS(num1+1);
rise[LF]++;
rise[RF]++;
}
if(Leave[LF] && Leave[RF])//离线人数分配
{
Leave[LF]--;
Leave[RF]--;
LemonDFS(num1+1);
Leave[LF]++;
Leave[RF]++;
}
return;
}
int main()
{
int T;
cin >> T;
while(T--)
{
memset(Lemon,0,sizeof(Lemon));
memset(Leave,0,sizeof(Leave));
memset(rise,0,sizeof(rise));
memset(num,0,sizeof(num));
//刷新4个数组的数据
sum=0;//记录 方法数量
cin >> n >> m;//输入人数量与朋友数量
for(int i=1;i<=m;i++)//开始标明第几号人有多少个朋友
{
cin >> Lemon[i].n1 >> Lemon[i].n2;
num[Lemon[i].n1]++;
num[Lemon[i].n2]++;
}
flag=0;//标记是否有方法
for(int i=1;i<=n;i++)
{
rise[i]=Leave[i]=num[i]/2;//如果朋友对是偶数才能同等分配,如果是奇数
//不满足条件,退出循环。
if(num[i]%2!=0)
{
flag=1;
break;
}
}
if(flag)//无方法的时候
{
printf("0\n");
}
else//有方法的时候就 DFS分配
{
LemonDFS(1);
printf("%d\n",sum);
}
}
}