HDU5952 Counting Cliques 暴搜优化

一、前言

  这题看上去相当唬人(NPC问题),但是 因为限制了一些条件,所以实际上并没有太唬人。

二、题目

  给你一个图,要求你找出数量为S的团的数量。

三、题解

  暴搜,再加上一些玄学优化。

  优化1:使用链表来优化图

  优化2:使用mapp【】【】来进行标记

  优化3:使用inline、define来进行优化

  优化4:无向图只从小节点指向大节点,优化边的数量

  优化5:初始化时使用精确控制memset字节数

//#include<bits/stdc++.h>
#include<stdio.h>
// #include<iostream>
#include<string.h>
// using namespace std;
#include<math.h>

#define ll long long
#define min(a,b) a<b ? a:b
#define max(a,b) a>b ? a:b

const ll MAXN=1233;

class Node
{
    public:
        int to,next;
};
Node G[MAXN*2];
int fst[123],size;

inline void add(int const&from,int const&to)
{
    G[size].next=fst[from];
    G[size].to=to;
    fst[from]=size++;
}
int n,m,s,cnt;
bool mapp[123][123];
int ans[MAXN];

inline bool check(int tar,int deep)
{
    for(int i=0;i<deep;++i)
    {
        if(!mapp[ans[i]][tar])return false;
    }return true;
}

void dfs(int now,int deep)
{
    if(deep==s)
    {
        cnt++;
        return ;
    }
    for(int i=fst[now];i!=-1;i=G[i].next)
    {
        int tar=G[i].to;
        if(tar<=now)continue;
        if(check(tar,deep))
        {
            ans[deep]=tar;
            dfs(tar,deep+1);
        }
    }
}

void init()
{
    size=0;
    scanf("%d%d%d",&n,&m,&s);
    memset(fst,-1,4*(n+23));
    memset(mapp,0,sizeof(mapp));
    for(int i=0;i<m;++i)
    {
        int a,b;
        scanf("%d%d",&a,&b);
        add(min(a,b),max(a,b));
        mapp[min(a,b)][max(a,b)]=1;
    }
    cnt=0;
    for(int i=1;i<=n;++i)ans[0]=i,dfs(i,1);
    printf("%d\n",cnt);
}

int main()
{
    int t;
    scanf("%d",&t);
//    cin>>t;
    while(t--)init();
}
时间: 2024-12-30 04:03:47

HDU5952 Counting Cliques 暴搜优化的相关文章

hdu5952 Counting Cliques 技巧dfs

题意:一个有N个点M条边的图,球其中由S个点构成的团的个数.一个团是一个完全子图. 没有什么好办法,只有暴力深搜,但是这里有一个神奇的操作:将无向图转为有向图:当两个点编号u<v时才有边u->v,这样的好处是一张完全图只有从最小编号开始深搜的时候才会搜完整张完全图(本来完全图从其中任意一个节点进入都是没有区别的),因为假如v1 < v2,并且v1,v2在同一完全图中,则v2只会走到编号更大的点,这样每张大小为S的完全图只有一条固定的路,所以不会重复.从1~N个点每个点开始dfs,这样即使

HDU5952 Counting Cliques(暴力)

题意: 100个点1000条边的图,问你有多少个s个点的团,每个节点的度不超过20 思路: 暴力..边太少,直接纯暴都可以 2106ms /* *********************************************** Author :devil ************************************************ */ #include <cstdio> #include <cstring> #include <iostrea

【算法系列学习】巧妙建图,暴搜去重 Counting Cliques

E - Counting Cliques http://blog.csdn.net/eventqueue/article/details/52973747 http://blog.csdn.net/yuanjunlai141/article/details/52972715 1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<string> 5 #include<

Sicily1317-Sudoku-位运算暴搜

最终代码地址:https://github.com/laiy/Datastructure-Algorithm/blob/master/sicily/1317.c 这题博主刷了1天,不是为了做出来,AC之后在那死磕性能... 累积交了45份代码,纪念一下- - 以上展示了从1.25s优化到0.03s的艰苦历程... 来看题目吧,就是一个数独求解的题: 1317. Sudoku Constraints Time Limit: 10 secs, Memory Limit: 32 MB Descript

hdu 4400 离散化+二分+BFS(暴搜剪枝还超时的时候可以借鉴一下)

Mines Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 1110    Accepted Submission(s): 280 Problem Description Terrorists put some mines in a crowded square recently. The police evacuate all peo

HDU 5952 Counting Cliques(dfs)

Counting Cliques Time Limit: 8000/4000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 1855    Accepted Submission(s): 735 Problem Description A clique is a complete graph, in which there is an edge between every pai

子矩阵(暴搜(全排列)+DP)

子矩阵(暴搜(全排列)+DP) 一.题目 子矩阵 时间限制: 1 Sec  内存限制: 128 MB 提交: 1  解决: 1 [提交][状态][讨论版] 题目描述 给出如下定义: 1. 子矩阵:从一个矩阵当中选取某些行和某些列交叉位置所组成的新矩阵(保持行与列的相对顺序)被称为原矩阵的一个子矩阵. 例如,下面左图中选取第2.4行和第2.4.5列交叉位置的元素得到一个2*3的子矩阵如右图所示. 9 3 3 3 9 9 4 8 7 4 1 7 4 6 6 6 8 5 6 9 7 4 5 6 1 的

【BZOJ-3033】太鼓达人 欧拉图 + 暴搜

3033: 太鼓达人 Time Limit: 1 Sec  Memory Limit: 128 MBSubmit: 204  Solved: 154[Submit][Status][Discuss] Description 七夕祭上,Vani牵着cl的手,在明亮的灯光和欢乐的气氛中愉快地穿行.这时,在前面忽然出现了一台太鼓达人机台,而在机台前坐着的是刚刚被精英队伍成员XLk.Poet_shy和lydrainbowcat拯救出来的的applepi.看到两人对太鼓达人产生了兴趣,applepi果断闪

c++20701除法(刘汝佳1、2册第七章,暴搜解决)

20701除法 难度级别: B: 编程语言:不限:运行时间限制:1000ms: 运行空间限制:51200KB: 代码长度限制:2000000B 试题描述     输入正整数n,按从小到大的顺序输出所有满足表达式abcde/fghij=n的abcde和fghij,其中a~j恰好为数字0~9的一个排列. 如果没有符合题意的数,输出0.本题所说的五位数可以包括前导0的,如01234在这里也称为五位数. 输入 一个正整数n  输出 若干行,每行包括两个符合要求的五位正整数(每行的两个数先大后小),两数之