7.23多校——5305DFS——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

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

Recommend

wange2014   |   We have carefully selected several similar problems for you:  5309 5308 5307 5306 5304

/*
cnt1[i]表示i顶点编号为1的度数
cnt2[i]表示i顶点编号为2的度数
显然得到如果存在一个点的度数为奇数,那么输出0(要平分)
如果顶点度数都是偶数,进行dfs,dfs边的数目,终止条件为cur == m (从0开始)
判断之前添的边能否满足
*/
#include <cstdio>
#include <algorithm>
#include <cstring>
using namespace std;

int n,m;
int cnt1[10], cnt2[10];
pair <int, int > a[100];

int ret;

bool check(int x)
{
    for(int i = 1; i <= x; i++){
        if(cnt1[i] != cnt2[i])
                return false;
    }
     return true;
}

void dfs(int cur)
{
    if(cur == m ){
        if(check(n))
            ret++;
        return ;
    }
    int u = a[cur].first;
    int v = a[cur].second;
    cnt1[u]++;
    cnt1[v]++;
    if(check(u-1)){
        dfs(cur + 1);
    }
    cnt1[u]--;
    cnt1[v]--;
    cnt2[u]++;
    cnt2[v]++;
    if(check(u-1)){
        dfs(cur + 1);
    }
    cnt2[u]--;
    cnt2[v]--;
}

int main()
{
    int T;
    int x, y;
    scanf("%d", &T);
    while(T--){
        scanf("%d%d", &n, &m);
        memset(cnt1, 0, sizeof(cnt1));
        memset(cnt2, 0, sizeof(cnt2));
        for(int i = 0; i < m ; i++){
            scanf("%d%d", &x, &y);
            if( x > y)
                swap(x, y);
            cnt1[x]++;
            cnt1[y]++;
            a[i] = make_pair(x, y);
        }
        int flag = 0;
        sort(a , a + m );
        for(int i = 1; i <= n ;i++)
            if(cnt1[i] % 2 == 1){
                flag = 1;
                break;
            }
        memset(cnt1, 0, sizeof(cnt1));
        ret = 0;
        dfs(0);
        if(flag == 0) printf("%d\n", ret);
        else printf("0\n");
    }
    return 0;
}

  

时间: 2024-10-29 19:08:55

7.23多校——5305DFS——Friends的相关文章

机器人II

1 /*机器人II 2 时间限制:1000 ms | 内存限制:65535 KB 3 难度:1 4 描述 5 自从xiao_wu发明了只能向左转与向右转的机器人以后,热血沸腾的他又给机器人加了一个操作.假设机器人在二维坐标系的原点, 6 一开始面向Y轴正方向(北N),现在给你一个仅由'L','R','M'的串,其中L表示向左转,R表示向右转,M表示向所面对的方向走一个单位的距离, 7 试问经过操作过后,机器人的坐标和所面对的方向. 8 北(N),西(W),东(E),南(S). 9 输入 10 第

D、Homework of PE 容斥原理

终于想懂了这个容斥, 华工4月23号校赛,考虑总的所有情况,设1---n里面含有质数的个数为all,需要固定m个质数.那么有 totSum = C(all, m) * (n - m)!,就是在all个质数里面,任意选m个出来固定,剩下的全排. 但是算多了,因为还有一些质数(不在那m个之内)也会被固定, 而且,考虑样例 5 1, 1 2 3 4 5 这个时候,先考虑任选m个出来固定,题目就是任选1个出来固定.剩下的全排 比如固定了2,剩下的全排,会产生,只固定了2,固定了2.3,固定了2.5,固定

中山大学校队选拔赛第一章题1【计算生成树】------2015年1月23日

1.1问题描述 1.2问题分析 本题主要考查图论中生成树及组合数学的求法.通过观察我们可以发现当输入为n时,我们一共有(5*n-n)=4n个点.通过思考我们可以知道,要想求得生成树,我们必须使所有五角形的圈全部破掉.那么我们可以思考: 如果对于一个五角形而言,它的每一条边都不删除,那么我们可以发现这必定不能构成生成树,因为这会导致在五角形内任意两个点会至少含有两条路径,不符合生成树的含义.所以我们可以得出如下结论: (1)对于有边数为n的回圈,我们可以发现一共有4n个点,共有5n条边.根据生成树

2014多校第十场1004 || HDU 4974 A simple water problem

题目链接 题意 : n支队伍,每场两个队伍表演,有可能两个队伍都得一分,也可能其中一个队伍一分,也可能都是0分,每个队伍将参加的场次得到的分数加起来,给你每个队伍最终得分,让你计算至少表演了几场. 思路 : ans = max(maxx,(sum+1)/2) :其实想想就可以,如果所有得分中最大值没有和的一半大,那就是队伍中一半一半对打,否则的话最大的那个就都包了. 1 #include <cstdio> 2 #include <cstring> 3 #include <st

HDOJ多校联合第五场

1001 题意:求逆序对,然后交换k次相邻的两个数,使得剩下的逆序对最少. 分析:题目用到的结论是:数组中存在一对逆序对,那么可以通过交换相邻两个数使得逆序对减少1,交换k次,可以最多减少k个. 嘉定ai>aj,i < j,如果ai,aj相邻的,那么显然可以通过交换减少1:不相邻的情况, 考虑ak,k = j-1; #11:ak > aj,那么ak,aj构成逆序对,交换后逆序对减少1: #12:ak<=aj,那么ai,ak构成逆序对,问题转化为更小规模,可以通过同样的方法进一步分析

linux通过ntpdate网络校时

目前 Linux 系统上面有两个时间喔,一个是 Linux 系统,另一个则是 BIOS 时间(真正的硬件记录的时间)! 我们可以使用 date 这个指令来手动修正目前主机的时间,不过, date 这个指令仅修正 Linux 时间而已,我们还需要以 hwclock 这个指令来将 BIOS 时间也更新才行! hwclock [-rw]     -r:查看现有BIOS时间     -w:将现在的linux系统时间写入BIOS中 当我们进行完 Linux 时间的校时后,还需要以 hwclock -w 来

实现基于NTP协议的网络校时功能

无论PC端还是移动端系统都自带时间同步功能,基于的都是NTP协议,这里使用C#来实现基于NTP协议的网络校时功能(也就是实现时间同步). 1.NTP原理 NTP[Network Time Protocol]是用来使计算机时间同步化的一种协议,它可以使计算机对其服务器或时钟源(如石英钟,GPS等等)做同步化,它可以提供高精准度的时间校正(LAN上与标准间差小于1毫秒,WAN上几十毫秒),且可介由加密确认的方式来防止恶毒的协议攻击. 先介绍下NTP数据包格式(其标准化文档为RFC2030,NTP版本

hdu 4972 A simple dynamic programming problem (转化 乱搞 思维题) 2014多校10

题目链接 题意:给定一个数组记录两队之间分差,只记分差,不记谁高谁低,问最终有多少种比分的可能性 分析: 类似cf的题目,比赛的时候都没想出来,简直笨到极点..... 1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <cstdlib> 5 #include <cmath> 6 #include <vector> 7 #include &

2014多校第七场1005 || HDU 4939 Stupid Tower Defense (DP)

题目链接 题意 :长度n单位,从头走到尾,经过每个单位长度需要花费t秒,有三种塔: 红塔 :经过该塔所在单位时,每秒会受到x点伤害. 绿塔 : 经过该塔所在单位之后的每个单位长度时每秒都会经受y点伤害. 蓝塔 : 经过该塔所在单位之后,再走每个单位长度的时候时间会变成t+z. 思路 : 官方题解 : 1 #include <cstdio> 2 #include <cstring> 3 #include <iostream> 4 #define LL long long