【HDU 5305】Friends 多校第二场(双向DFS)

依据题意的话最多32条边,直接暴力的话 2 ^ 32肯定超时了。我们能够分两次搜索时间复杂度降低为 2 * 2  ^ 16

唯一须要注意的就是对眼下状态的哈希处理。

我採用的是 十进制表示法

跑的还是比較快的,可能是用STL函数的原因添加了一些常数复杂度。

#include<map>
#include<vector>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long LL;
typedef pair<int,int> pill;
const int maxn = 55;
struct Edge{
    int a,b;
}edge[maxn];
int n,m;
LL cnt,base[15];
int _count[15];
map<pill,int>vis;
void init(){
    base[1] = 1;
    for(int i = 2; i < 10; i++)
        base[i] = base[i - 1] * 10;
}
void calc(int state1,int state2,int &a,int &b){
    int base = 1;
    for(int i = 1; i <= n; i++){
        int d1 = state1 % 10, d2 = state2 % 10;
        int v1 = _count[i] - d1, v2 = _count[i] - d2;
        a += base * v1;
        b += base * v2;
        base *= 10;
        state1 /= 10;
        state2 /= 10;
    }
}
void dfs1(int now,int finish,int state1,int state2){
    if(now == finish){
        vis[make_pair(state1,state2)] ++;
        return;
    }
    int a = edge[now].a, b = edge[now].b;
    dfs1(now + 1,finish,state1 + base[a] + base[b],state2);
    dfs1(now + 1,finish,state1,state2 + base[a] + base[b]);
}
void dfs2(int now,int finish,int state1,int state2){
    if(now == finish){
        int x = 0,y = 0;
        calc(state1,state2,x,y);
        if(x >= 0 && y >= 0)
            cnt += vis[make_pair(x,y)];
        return;
    }
    int a = edge[now].a, b = edge[now].b;
    dfs2(now + 1,finish,state1 + base[a] + base[b],state2);
    dfs2(now + 1,finish,state1,state2 + base[a] + base[b]);
}
int main(){
    int T;
    init();
    scanf("%d",&T);
    while(T--){
        vis.clear();
        memset(_count,0,sizeof(_count));
        scanf("%d%d",&n,&m);
        for(int i = 0; i < m; i++){
            scanf("%d%d",&edge[i].a,&edge[i].b);
            _count[edge[i].a] ++;
            _count[edge[i].b] ++;
        }
        int ok = 1;
        for(int i = 1; i <= n; i++){
            if(_count[i] % 2 != 0){
                ok = 0;
                break;
            }
            _count[i] /= 2;
        }
        cnt = 0;
        if(ok){
            dfs1(0,m / 2,0,0);
            dfs2(m / 2,m,0,0);
        }
        printf("%d\n",cnt);
    }
    return 0;
}
时间: 2024-10-12 07:41:01

【HDU 5305】Friends 多校第二场(双向DFS)的相关文章

多校第二场 简单排序计算

思路:先按交叉相乘之差排序好了计算就行了. #include <iostream> #include <cstdio> #include <cstring> #include <cmath> #include <map> #include <cstdlib> #include <queue> #include <stack> #include <vector> #include <ctype.

hdu 5305 Friends(2015多校第二场第6题)记忆化搜索

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5305 题意:给你n个人,m条关系,关系可以是online也可以是offline,让你求在保证所有人online关系的朋友和offline关系的朋友相等的情况下,这样的情况有多少种. 思路:因为online关系和offline关系的人数相等,而且m最多才28,所以只要枚举每个人的一半的关系是否符合要求即可,而且根据题意m是奇数或者有一个人的总关系为奇数那么就没有符合要求的情况,这样可以排除很多情况.

HDU 5305 Friends(2015多校第二场 dfs + 剪枝)

Friends Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Total Submission(s): 552    Accepted Submission(s): 253 Problem Description There are  people and  pairs of friends. For every pair of friends, they can choos

hdu 5308 (2015多校第二场第9题)脑洞模拟题,无语

题目链接:http://acm.hdu.edu.cn/listproblem.php?vol=44 题意:给你n个n,如果能在n-1次运算之后(加减乘除)结果为24的输出n-1次运算的过程,如果不能输出-1. 思路:乍看起来,没什么规律,但是可以想象的是(n+n+n+n)/n=4,(n+n+n+n+n+n)/n=6,(n-n)*n*n*·····*n=0所以在n大于15的时候结果基本是固定的,只要对小于15的数一一输出就行(但是这题真是无语,算这种题目真是累,脑洞啊~~) 代码: 1 #incl

hdu 5301 Buildings (2015多校第二场第2题) 简单模拟

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5301 题意:给你一个n*m的矩形,可以分成n*m个1*1的小矩形,再给你一个坐标(x,y),表示黑格子在n*m矩形中的位置,黑格子占一个1*1的小矩形的空间,用各种矩形去填充n*m矩形,(x,y)位置不能填,且每个去填充的小矩形都有一边是靠着n*m矩形的外框,求这些填充的小矩形在最小大小情况下的面积最大的矩形面积. 思路:要是填充的矩形大小最小,那么靠近边框的长度一定为1,所以只要判断在矩形内部的长

HDU6602 Longest Subarray hdu多校第二场 线段树

HDU6602 Longest Subarray 线段树 传送门:http://acm.hdu.edu.cn/showproblem.php?pid=6602 题意: 给你一段区间,让你求最长的区间使得区间出现的数字的个数大于k 题解: 比较巧妙的的线段树更新的做法 我们选择的区间吗,该区间内出现的数字的个数必须要满足条件 我们转换一下,我们以当前点为右端点,往左找一个满足条件的左端点,即可更新答案 我们将每个点给予一个权值C-1,更新这个点的数字上次出现的位置之前到现在这个位置-1的一段减1

多校第二场 1004 hdu 5303 Delicious Apples(背包+贪心)

题目链接: 点击打开链接 题目大意: 在一个周长为L的环上.给出n棵苹果树.苹果树的位置是xi,苹果树是ai,苹果商店在0位置,人的篮子最大容量为k,问最少做多远的距离可以把苹果都运到店里 题目分析: 首先我们能够(ˇ?ˇ) 想-,假设在走半圆之内能够装满,那么一定优于绕一圈回到起点.所以我们从中点将这个圈劈开.那么对于每一个区间由于苹果数非常少,所以能够利用belong[x]数组记录每一个苹果所在的苹果树位置,然后将苹果依照所在的位置排序,那么也就是我们知道每次拿k个苹果的代价是苹果所在的最远

HDU 5301 Buildings(2015多校第二场)

Buildings Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others) Total Submission(s): 759    Accepted Submission(s): 210 Problem Description Your current task is to make a ground plan for a residential building located

hdu 5734 Acperience(2016多校第二场)

Acperience Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 484    Accepted Submission(s): 258 Problem Description Deep neural networks (DNN) have shown significant improvements in several applic