zoukankan      html  css  js  c++  java
  • HDU 5952 [DFS]

    题目链接:【http://acm.hdu.edu.cn/showproblem.php?pid=5952】

    题意:给出一张无向图,然后判断这张图中一共有多少个不同的大小为S的完全图,并且保证每个点的度不大于20。

    题解:好吧,比赛的时候想太多了,结果时间刚不住,TTTT。正解其实很简单,就一个DFS。每次建立DFS(u),表示u在的大小为S的完全图个数,为了保证不重复,我们只建立单向边。每层DFS的时候,取一个点,当且仅的这个点与之前的所有点选过的点有边相连(神优化)。总复杂度是100 * 100 * (2 ^ 19) ,但是,应为边很少,所以,复杂度要少很多。

    思维僵化啊。

    #include<Bits/stdc++.h>
    using namespace std;
    const int maxn = 105;
    int T, N, M, S;
    struct Edge
    {
        int to, next;
        Edge() {}
        Edge(int to, int next): to(to), next(next) {}
    } E[2050];
    int head[maxn], tot;
    int mp[maxn][maxn], vis[maxn], tmp[maxn];
    int ans = 0;
    void initEdge()
    {
        for(int i = 0; i <= N; i++) head[i] = -1;
        tot = 0;
    }
    void addEdge(int u, int v)
    {
        E[tot] = Edge(v, head[u]);
        head[u] = tot++;
    }
    void DFS(int u, int pos)
    {
        if(pos == S)
        {
            ans++;
            return ;
        }
        for(int k = head[u]; ~k; k = E[k].next)
        {
            int v = E[k].to;
            bool fg = true;
            for(int i = 0; i < pos && fg; i++)
                if(!mp[v][tmp[i]]) fg = false;
            if(fg)
            {
                tmp[pos] = v;
                DFS(v, pos + 1);
            }
        }
        return ;
    }
    int main ()
    {
        scanf("%d", &T);
        while(T--)
        {
            scanf("%d %d %d", &N, &M, &S);
            initEdge();
            for(int i = 1; i <= N; i++)
            {
                vis[i] = 0;
                for(int j = i + 1; j <= N; j++)
                    mp[i][j] = mp[j][i] = 0;
            }
            for(int i = 1; i <= M; i++)
            {
                int u, v;
                scanf("%d %d", &u, &v);
                addEdge(u, v);
                mp[u][v] = mp[v][u] = 1;
            }
            if(S == 2)
            {
                printf("%d
    ", M);
                continue;
            }
            ans = 0;
            for(int i = 1; i <= N; i++)
            {
                tmp[0] = i;
                DFS(i, 1);
            }
    
            printf("%d
    ", ans);
        }
        return 0;
    }
    

      

  • 相关阅读:
    树莓派交叉编译环境搭建
    手机购买怎样识别假货——一点心得体会分享!
    Ubuntu 网站服务器环境搭建
    转载:Raspberry Pi 树莓派入门
    Python中的条件选择和循环语句
    关于VMare中安装Ubuntu的一些说明
    如何去掉系统快捷方式的箭头和更改登录界面背景图片
    重装系统后,硬盘分区丢失的解决办法
    Python中的字符串
    Python的基础语法
  • 原文地址:https://www.cnblogs.com/pealicx/p/7577140.html
Copyright © 2011-2022 走看看