POJ 1419
题目链接:
http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=17391
题意:
给一个图,要求把图中点染色,规则是一个点如果染成黑色,则有边相连的其他点不能染成黑色。
问怎样选取最多的点染成黑色。输出点个数和选取方案。
思路:
最大独立集:一个图中最大的互相没有边相连的点集。
结论:原图的最大独立集等于补图的最大团
源码:
#include <cstdio>
#include <cstring>
#include <cmath>
#include <cstdlib>
#include <algorithm>
#include <iostream>
#include <string>
#include <vector>
using namespace std;
const int MAXN = 100 + 5;
int gra[MAXN][MAXN];
int vis[MAXN];
int val[MAXN];
int ans[MAXN], cnt;
int n, m;
bool check(int mark)
{
for(int i = 1 ; i < mark ; i++)
if(vis[i] && gra[i][mark] == 0)
return false;
return true;
}
void DFS(int mark, int num)
{
if(num > cnt){
cnt = num;
int now = 0;
for(int i = 1 ; i <= n ; i++){
if(vis[i])
ans[now++] = i;
}
}
for(int i = mark + 1 ; i <= n ; i++){
if(check(i)){
vis[i] = 1;
DFS(i, num + 1);
vis[i] = 0;
}
}
}
int main()
{
int t;
scanf("%d", &t);
while(t--){
scanf("%d%d", &n, &m);
for(int i = 1 ; i <= n ; i++)
for(int j = 1 ; j <= n ; j++)
gra[i][j] = 1;
int u, v;
for(int i = 0 ; i < m ; i++){
scanf("%d%d", &u, &v);
gra[u][v] = gra[v][u] = 0;
}
cnt = 0;
memset(vis, 0, sizeof(vis));
for(int i = 1 ; i <= n ; i++){
vis[i] = 1;
DFS(i, 1);
vis[i] = 0;
}
printf("%d\n", cnt);
int f = 1;
for(int i = 0 ; i < cnt ; i++){
if(f) f = 0;
else printf(" ");
printf("%d", ans[i]);
}
printf("\n");
}
return 0;
}