最大独立集 = 补图的最大团
最小顶点覆盖 + 最大独立集 = V
#include <stdio.h> #include <string.h> const int maxn =100 + 10; int g[maxn][maxn], dp[maxn], n; int x[maxn], ans[maxn], mx; int dfs(int *adj, int ns, int dep) { int t[maxn]; if(0 == ns) { if(dep > mx) { for(int i=0; i<dep; ++i) ans[i] = x[i]; //路径信息 mx = dep; return 1; } return 0; } int i, j, cnt; for(i=0; i < ns; ++i) { int& k = adj[i]; if(dep + n - k <= mx) return 0; if(dep + dp[k] <= mx) return 0; x[dep] = k; //路径信息 for(cnt =0, j = i+1; j < ns; ++j) { int& p = adj[j]; if(g[k][p]) t[cnt++]= p; } if(dfs(t, cnt, dep+1)) return 1; } return 0; } int max_clique(int n) { int i, j, ns; int adj[maxn]; if(n<=0) return 0; mx = 0; for(i = n-1; i >= 0; --i) { x[0] = i; //路径信息 for(ns = 0, j=i+1; j < n; ++j) if(g[i][j]) adj[ns++] = j; dfs(adj, ns, 1); dp[i] = mx; } return mx; } int main() { int t, m, i, j, v, u; scanf("%d",&t); while(t--) { scanf("%d%d",&n,&m); for(i=0; i<=n; ++i) for(j=0; j<=n; ++j) g[i][j] = 1; for(i=0; i<m; ++i) { scanf("%d%d",&v,&u); v--;u--; g[v][u] = g[u][v] = 0; } int mmax = max_clique(n); printf("%d\n",mmax); for(i=0; i<mmax; ++i) { printf("%d ",ans[i]+1); } printf("\n"); } return 0; }
时间: 2024-12-18 12:46:53