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
",cnt);
}

int main()
{
    int t;
    scanf("%d",&t);
//    cin>>t;
    while(t--)init();
}
原文地址:https://www.cnblogs.com/rikka/p/8031946.html