最大團問題:團(clique)是圖論中的用語。對於給定圖G=(V,E)。其中,V={1,…,n}是圖G的頂點集,E是圖G的邊集。圖G的團就是一個兩兩之間有邊的頂點集合。如果一個團不被其他任一團所包含,即它不是其他任一團的真子集,則稱該團為圖G的極大團(maximal clique)。頂點最多的極大團,稱之為圖G的最大團(maximum clique)。最大團問題的目標就是要找到給定圖的最大團。
http://zh.wikipedia.org/wiki/%E5%9C%98_(%E5%9C%96%E8%AB%96)
1 /*==================================================*\ 2 | 最大團問題 DP + DFS 3 | INIT: g[][]鄰接矩陣; 4 | CALL: res = clique(n); 5 \*==================================================*/ 6 const int V = 10; 7 int g[V][V], dp[V], stk[V][V], mx; 8 //dp[i]:從i到n-1的最大的團 9 //mx最后的結果 10 //stk[i][j]:第i層中與之相連的第j大的標號 11 12 13 14 //總共有n個數,dep代表當前的層數,ns代表於當前層相連的並且比ns大的標號的個數 15 int dfs(int n, int ns, int dep) { 16 if (0 == ns) { 17 if (dep > mx) 18 mx = dep; 19 return 1; 20 } 21 int i, j, k, p, cnt; 22 for (i = 0; i < ns; i++) { 23 k = stk[dep][i];//與之相連的第i個點 24 25 if (dep + n - k <= mx)//當前層數+第k層下邊的<=mx,則不再搜索 26 return 0; 27 if (dep + dp[k] <= mx)//當前層數+dp的最大的<=mx,不再搜索 28 return 0; 29 30 cnt = 0; 31 for (j = i + 1; j < ns; j++) { 32 p = stk[dep][j];//i后邊的某個點 33 if (g[k][p])//如果i和j相連 34 stk[dep + 1][cnt++] = p;//如果沒有與之相連的,則cnt為0 35 } 36 dfs(n, cnt, dep + 1); 37 } 38 return 1; 39 } 40 int clique(int n) { 41 int i, j, ns; 42 mx = 0; 43 for ( i = n - 1; i >= 0; i--) {//dp用的 44 // vertex: 0 ~ n-1 45 ns = 0; 46 for (j = i + 1; j < n; j++) 47 if (g[i][j]) 48 stk[1][ns++] = j; 49 dfs(n, ns, 1); 50 dp[i] = mx; 51 } 52 return mx; 53 }