HDU - 5952 Counting Cliques

Counting Cliques

HDU - 5952

OJ-ID:
hdu-5952

author:
Caution_X

date of submission:
20191110

tags:
dfs,graph

description modelling:
給定點數,邊數,問包含有x個點的徹底圖種類數

major steps to solve it:
(1)選擇一個點做爲起點,記錄該起點的全部連通點,dfs(該點)此時徹底圖有兩個點
(2)遍歷(1)中選定點的連通點,若構成徹底圖,則dfs(可以與(1)的圖構成徹底圖的點)此時徹底圖有三個點 以此類推 當徹底圖點數=x時結束dfs
(3)重複(2)操做直到全部點都被做爲起點使用過

warnings:
由於每個起點都知足含有[2,x]個點的徹底圖,所以,不一樣起點達到x個點時的徹底圖相互獨立

spa

AC code:.net

#include<cstdio>
#include<algorithm>
#include<string.h>
#include<bitset>
using namespace std;
const int maxn = 105;
int s,ans;
bool mp[maxn][maxn];
/*
這裏的dfs看起來很簡單,其實包含了一個很大的剪枝:在遍歷某個點的時候,已經肯定了已經加入團的點是與這個點相連的,還能夠知道平均下來每一個點的入度不會超過20,
所以整個遍歷的複雜度最高是C(9,20)*100
*/
void dfs(int mx,int v[],int cnt){
    int nxt[maxn];
    if(cnt==s) {ans++;return;}
    for(int i=0;i<mx;i++){           //枚舉能與點數爲cnt的團構成點數爲cnt+1的團的全部點
        int len=0;
        for(int j=i+1;j<mx;j++){
            if(mp[v[i]][v[j]]){    //該團的全部"候選點"必須與已經選了的點相連
                nxt[len++]=v[j];
            }
        }
        dfs(len,nxt,cnt+1);
    }
}
int main(){
    int T,n,m,u,v;
   // freopen("in.txt","r",stdin);
    scanf("%d",&T);
    while(T--){
        scanf("%d%d%d",&n,&m,&s);
        memset(mp,0,sizeof(mp));
        for(int i=0;i<m;i++){
            scanf("%d%d",&u,&v);
            mp[u][v]=mp[v][u]=1;
        }
        ans=0;
        int nxt[105];
        for(int i=1;i<=n;i++){      //枚舉每一個點,這個點必須在所求的團裏面,以這個點開始搜索
            int len=0;
            for(int j=i+1;j<=n;j++){
                if(mp[i][j]){      //該團的全部"候選點"必須與已經選了的點相連
                    nxt[len++]=j;
                }
            }
            dfs(len,nxt,1);
        }
        printf("%d\n",ans);
    }
    return 0;
}
相關文章
相關標籤/搜索