hdu-5952 Counting Cliques(dfs&&優化)
阿新 • • 發佈:2018-12-13
題意:
給一個無向圖,N(0-100)個頂點,M(0-1000)條邊,求圖中頂點數為S(1-10)的完全圖(任意兩個頂點都有一條邊相連)的個數。
思路:
最開始還以為是環,這鍋sls得背啊哈哈哈哈。
題解都在註釋裡了。
#include <iostream> #include <cstring> #include <cstdio> #include <algorithm> #include <queue> #include <map> #include <set> #include <iterator> using namespace std; const int maxn = 100+10; int n,m,s; vector<int> node[maxn]; int vis[maxn]; bool mark[maxn][maxn]; long long ans=0; void dfs(int i,int cnt) { if(cnt==s) { ans++; return; } for(int j=0; j<node[i].size(); j++)//因為之前的處理,這裡加入的點編號一定比i大,所以會減少不必要搜尋,而且不會重複。這是最重要的優化!! { int no=node[i][j]; //i相鄰點的編號 bool flag=1; for(int l=1; l<=cnt; ++l) { if(mark[no][vis[l]]==0)//新加入的點必須與原圖任意一點都相連,否則不是完全圖 { flag=0; break; } } if(flag) { vis[cnt+1]=no;//加入新點 dfs(no,cnt+1); vis[cnt+1]=0; } } return ; } int main() { int t,st,ed; scanf("%d",&t); while(t--) { memset(mark,0,sizeof mark); ans=0; scanf("%d%d%d",&n,&m,&s); for(int i=0; i<maxn; i++) { node[i].clear(); } for(int i=0; i<m; i++) { scanf("%d%d",&st,&ed); if(st>ed) //node[i]只存編號比i大的點得編號 node[st].push_back(ed); else node[ed].push_back(st); mark[st][ed]=1;//標記這條邊存在 mark[ed][st]=1; } for(int i=1; i<=n; i++) { vis[1]=i; dfs(i,1);//以i為起點的點的個數為s的完全圖的個數 vis[1]=0; } printf("%lld\n",ans); } return 0; }