POJ——Graph Coloring

Graph Coloring

描述

如图,我们可以给一幅图上色,要求黑色的颜色不能相邻。求问该如何上色,使得黑色的点最多?
1.png

问题分析

求不相邻的最大值——求一幅图的最大独立集。我们先建立图的补集,然后再求最大团。最大团的大小就是最多的点数量

代码

#include<iostream>
#include<cstdio>
#include<cstring>
#include<vector>
using namespace std;
const int maxn = 100 + 10;
int kase,n,m,best,num[maxn],mat[maxn][maxn];
vector<int> ans;

bool dfs(int *adj,int tot,int cnt,vector<int> vec)
{
  int i,j,k,t[maxn];
  if(tot == 0)
  {
    if(cnt > best)
    {
      ans = vec;
      best = cnt;
      return true;
    }
    else return false;
  }
  for(i=0;i<tot;i++)
  {
    if(cnt + (tot - i) <= best) return false;
    if(cnt + num[adj[i]] <= best) return false;
    for(k=0,j=i+1;j<tot;j++)
      if(mat[adj[i]][adj[j]]) t[k++] = adj[j];
    vec.push_back(adj[i]);
    if(dfs(t,k,cnt+1,vec))  return true;
    vec.pop_back();
  }
  return false;
}

int max_clique()
{
  int i,j,k,adj[maxn];
  vector<int> vec;
  if(n <= 0)  return 0;
  best = 0;
  for(i=n;i>0;i--)
  {
    for(k=0,j=i+1;j<=n;j++)
      if(mat[i][j]) adj[k++] = j;
    vec.push_back(i);
    dfs(adj,k,1,vec);
    num[i] = best;
    vec.pop_back();
  }
  return best;
}

int main()
{
  ios::sync_with_stdio(false);cin.tie(0);
  int a,b;
  cin >> kase;
  while(kase--)
  {
    memset(mat,1,sizeof(mat));
    cin >> n >> m;
    for(int i=0;i<m;i++)
    {
      cin >> a >> b;
      mat[a][b] = mat[b][a] = 0;
    }
    max_clique();
    cout << best << endl;
    for(int i=0;i<best;i++)
    {
      if(i == 0)  cout << ans[i];
      else cout << " " << ans[i];
    }
    if(best > 0)  cout << endl;
  }
}
... ... ...