最大团问题:团(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 }