图的点着色、区间着色问题及其应用(基于贪心思想的DFS回溯法求点着色问题和区间着色算法求解任务调度问题)

Link:http://poj.org/problem?id=1419


Graph Coloring
Time Limit: 1000MS   Memory Limit: 10000K
Total Submissions: 4503   Accepted: 2059   Special Judge

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表
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

林下的码路

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值