Link:http://poj.org/problem?id=1419
Graph Coloring
Description
You are to write a program that tries to find an optimal coloring for a given graph. Colors are applied to the nodes of the graph and the only available colors are black and white. The coloring of the graph is called optimal if a maximum of nodes is black. The coloring is restricted by the rule that no two connected nodes may be black.
![]() Figure 1: An optimal graph with three black nodes Input
The graph is given as a set of nodes denoted by numbers 1...n, n <= 100, and a set of undirected edges denoted by pairs of node numbers (n1, n2), n1 != n2. The input file contains m graphs. The number m is given on the first line. The first line of each graph contains n and k, the number of nodes and the number of edges, respectively. The following k lines contain the edges given by a pair of node numbers, which are separated by a space.
Output
The output should consists of 2m lines, two lines for each graph found in the input file. The first line of should contain the maximum number of nodes that can be colored black in the graph. The second line should contain one possible optimal coloring. It is given by the list of black nodes, separated by a blank.
Sample Input 1 6 8 1 2 1 3 2 4 2 5 3 4 3 6 4 6 5 6 Sample Output 3 1 4 5 Source |
题意:求出在合法条件(The coloring is restricted by the rule that no two connected nodes may be black. )下的方案使得染成黑色的顶点最多。
下面解题思路和算法描述来自:http://blog.youkuaiyun.com/wall_f/article/details/8190324
思路:在这一题中,题目给定的图一定是二分图,所以我们可以用到一种基于贪心思想的染色算法--顺序染色法,有的图是不能用顺序染色法来求解的。这种算法是一种近似的有效算法。由于每次从u最小的邻接顶点开始染色,所以输出的数字一定是严格的上升序。
顺序染色:
(1)用i表示顶点序号,i=1;
(2)用c表示给顶点i着色为第c中颜色,c=1;
(3)对第i个顶点着色:考虑它的每个邻接顶点,如果都没有使用第c中颜色 ,则给顶点i着色为第c种颜色,并转向第(5)步;否则,转向第(4)步。
(4)c = c+1,并转向第(3)步。
(5)若还有其他的顶点未着色,则i = i+1,并转向第(2)步,否则算法结束。
注意,这只是一种近似的有效算法。例如,二分图中i就可以用顺序染色,而有的图用这种算法求出来的结果是错误的。
My AC code:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <vector>
#include <string>
#include <queue>
#include <stack>
#include <algorithm>
#define PI acos(-1.0)
#define LINF 1000000000000000000LL
#define eps 1e-8
#define LL long long
#define MAXN 100010
#define MOD 1000000007
using namespace std;
const int INF=0x3f3f3f3f;
int color[111];
vector<int>vec[111];//vec[i]存储第i种着色方案
vector<int>e[111];//边
int cnt,n;//n为顶点数,cnt为黑色的点数 ,cnti可指定求在某一种特定条件下的最优方案是第几种方案
int ans,ansi;
bool Ok(int k)//k表示第k个顶点
{
if(color[k]==1)
{
for(int i=0;i<e[k].size();i++)
{
if(color[e[k][i]]==color[k])
return false;
}
}
return true;
}
void dfs(int u,int color_num)//u为顶点编号,注意:着色问题深搜是按顶点编号深搜下去,不是沿着邻边的下个顶点深搜下去!!!
{
if(u==n+1)//第(5)步
{
/*for(int i=1;i<=n;i++)//输出所有染色方案
{
printf("%d",color[i]);
}
puts("");*/
if(cnt>ansi)
{
ansi=cnt;
for(int i=1;i<=n;i++)
{
if(color[i]==1)
vec[ansi].push_back(i);
}
}
return;
}
if(cnt+(n-u)+1<=ansi)//剪枝,若就算剩下的点数都可以染成黑色,再加上当前黑色的点数还没有前面的染色方案得到的最大黑色点数多,则舍弃当前这种方案
return;
for(int co=1;co<=color_num;co++)//color_num表示颜色种类数,1表示黑色,2表