思路:dfs。
稍微暴力版:
# include <iostream> # include <cstdio> # include <cstring> using namespace std; int m[53][53], n, vis[53], cnt, ans; void dfs(int x) { if(x > n) { ans = max(ans, cnt); return; } int flag = 1; for(int i=1; i<x; ++i) { if(vis[i] && !m[i][x]) { flag = 0; break; } } if(flag) { vis[x] = 1, ++cnt; dfs(x+1); vis[x] = 0, --cnt; } if(n-x+cnt > ans) dfs(x+1); } int main() { while(~scanf("%d",&n),n) { cnt = ans = 0; memset(vis, 0, sizeof(vis)); for(int i=1; i<=n; ++i) for(int j=1; j<=n; ++j) scanf("%d",&m[i][j]); dfs(1); printf("%d\n",ans); } return 0; } dp版: # include <iostream> # include <cstdio> # include <cstring> using namespace std; int m[53][53], n, ans, dp[53], a[53][53];//dp[i]表示在第i个数到后面可以选的最大团。 void dfs(int up, int dep) { if(up == 0) { ans = max(ans, dep); return; } for(int i=0; i<up; ++i) { int cnt = 0; int u = a[dep][i]; if(dep + n - u + 1 <= ans) return; if(dep + dp[u] <= ans) return; for(int j=i+1; j<up; ++j) { int v = a[dep][j]; if(m[u][v]) a[dep+1][cnt++] = v; } dfs(cnt, dep+1); } } int clique() { for(int i=n; i>0; --i) { int cnt = 0; for(int j=i+1; j<=n; ++j) { if(m[i][j]) a[1][cnt++] = j; } dfs(cnt, 1); dp[i] = ans; } return ans; } int main() { while(~scanf("%d",&n),n) { ans = 0; memset(a, 0, sizeof(a)); memset(dp, 0, sizeof(dp)); for(int i=1; i<=n; ++i) for(int j=1; j<=n; ++j) scanf("%d",&m[i][j]); printf("%d\n",clique()); } return 0; }