• 【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
    ",cnt);
        }
        return 0;
    }
    

  • 相关阅读:
    window下上传文件至linux(windows下如何访问linux)
    32位除法器的verilog语言实现
    socket编程——TCP数据传输的可靠与稳定性
    socket编程——TCP连接与断开
    C踩坑纪实——(一)
    CMAKE工具学习
    排序算法优化思考
    MQTT抓包分析
    C结构体与链表
    第二次作业
  • 原文地址:https://www.cnblogs.com/tlnshuju/p/6830734.html
Copyright © 2020-2023  润新知