题意:给了一个有 n 个点 m 条边的无向图,要求用黑、白两种色给图中顶点涂色,相邻的两个顶点不能涂成黑色,求最多能有多少顶点涂成黑色。图中最多有 100 个点
该题是求最大独立集团 最大团点的数量=补图中最大独立集点的数量 ----->最大独立集团的数量 =补图中最大团点的数量 是完全对称的
并且要打印出点
#include<cstdio> #include<cstring> #include<iostream> using namespace std; #define N 110 int n; int mp[N][N]; int ans; int alt[N][N]; int Max[N]; int path[N]; int anspath[N]; bool dfs(int cur,int tot)//cur是s1集合的个数 { if(0==cur) { if(tot>ans) { ans=tot; for(int i=1;i<=tot;i++)anspath[i]=path[i]; return true; } return false; } for(int i=0;i<cur;i++) { if( tot+cur-i<=ans )return false; int u=alt[tot][i]; if( Max[u]+tot<=ans )return false; int next=0; for(int j=i+1;j<cur;j++) if(mp[u][ alt[tot][j] ])alt[tot+1][next++]=alt[tot][j]; path[tot+1]=u; if(dfs(next,tot+1)) return 1; } return 0; } int maxclique(void) { ans=0; memset(Max,0,sizeof(Max)); for(int i=n-1;i>=0;i--) { int cur=0; path[1]=i; for(int j=i+1;j<n;j++)if(mp[i][j])alt[1][cur++]=j;//1为s1集合 dfs(cur,1); Max[i]=ans; } return ans; } int main() { int cas; cin>>cas; while(cas--) { int m; memset(mp,1,sizeof mp); scanf("%d%d",&n,&m); while(m--) { int a,b; scanf("%d%d",&a,&b); mp[a-1][b-1]=mp[b-1][a-1]=0; } int k=maxclique(); printf("%d\n",k); for(int i=1;i<=k;i++) { printf("%d",anspath[i]+1); if(i==k)printf("\n"); else printf(" "); } } return 0; }