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; }