UVa 1613 K-Graph Oddity

You are given a connected undirected graph with an odd number of vertices. The degree of the vertex, by definition, is the number of edges incident to it. In the given graph the degree of each vertex does not exceed an odd number k. Your task is to color the vertices of this graph into at most k distinct colors, so that the colors of any two adjacent vertices are distinct.

The pictures below show two graphs. The first one has 3 vertices and the second one has 7 vertices. In both graphs degrees of the vertices do not exceed 3 and the vertices are colored into at most 3 different colors marked as ` \epsfbox{p4993a.eps}', ` \epsfbox{p4993b.eps} ' and ` \epsfbox{p4993c.eps} '.

\epsfbox{p4993d.eps}

Input 

The input will contain several test cases, each of them as described below. Consecutive test cases are separated by a single blank line.


The first line of the input file contains two integer numbers n and m, where n is the number of vertices in the graph (3$ \le$n$ \le$9999n is odd), m is the number of edges in the graph (2$ \le$m$ \le$100000). The following m lines describe edges of the graph, each edge is described by two integers aibi (1$ \le$aibi$ \le$nai = bi) -- the vertex numbers connected by this edge. Each edge is listed at most once. The graph in the input file is connected, so there is a path between any pair of vertices.

Output 

For each test case, the output must follow the description below. The outputs of two consecutive cases will be separated by a blank line.


On the first line of the output file write a single integer number k -- the minimal odd integer number, such that the degree of any vertex does not exceed k. Then write n lines with one integer number ci (1$ \le$ci$ \le$k) on a line that denotes the color of i-th vertex.

The colors of any two adjacent vertices must be different. If the graph has multiple different colorings, print any of them. At least one such coloring always exists.

Sample Input 

3 2 
1 3 
3 2 

7 8
1 4
4 2
2 6
6 3
3 7
4 5
5 6
5 2

Sample Output 

3 
1 
1 
2
 
3 
1 
1 
1 
2 
3 
2 
2
 
#include <cstdio>
#include <vector>
#include <algorithm>
using namespace std;

// 顶点的可选的颜色
int degree[10010];

// 顶点选择的颜色
int color[10010];

// 图,next[i]代表和i相邻的节点 
vector<int> next[10010];

// 顶点个数,边个数
int n, m;

int k;

int main()
{
	int count = 0;
	while(scanf("%d %d", &n, &m) == 2)
	{
		for(int i = 1; i <= n; i++)
		{
			next[i] = vector<int>();
			color[i] = 0;
			degree[i] = 0;
		}

		int max_degree = 0;		
		for(int i = 1; i <= m; i++)
		{
			int x, y;
			scanf("%d %d", &x, &y);
			degree[x]++;
			degree[y]++;
			next[x].push_back(y);
			next[y].push_back(x);
			int t_max = max(degree[x],degree[y]);	
			max_degree = t_max > max_degree ? t_max : max_degree;		
		}
		if(max_degree % 2 == 0)
			k = max_degree+1;
		else
			k = max_degree;

		
		for(int i = 1; i <= n; i++)					
			degree[i] = k-degree[i];
	
		// 依次为可选颜色最小的顶点选定颜色
		for(int i = 1; i <= n; i++)
		{
			int p;
			int min_degree = 20000;
			for(int j = 1; j <= n; j++)
			{
				if(color[j] == 0 && min_degree > degree[j])
				{
					min_degree = degree[j];
					p = j;
				}
			}

			// 根据该点的相邻点已选的颜色来确定该点的颜色
			int not_color[10010];
			for(int j = 1; j <= k; j++)
				not_color[j] = 0;
		
			for(int j = 0; j < next[p].size(); j++)
			{
				if(color[next[p][j]] != 0)
				{
					not_color[color[next[p][j]]] = 1;
				}
			}		
			for(int j = 1; j <= k; j++)
			{
				if(not_color[j] == 0)
				{
					color[p] = j;
					break;
				}
			}	

			// 更新该点相邻点可选的颜色数目
			for(int j = 0; j < next[p].size(); j++)
			{
				if(color[next[p][j]] == 0)
				{
					degree[next[p][j]]--;
				}
			}
	
		}

		// 输出
		if(count > 0)
			printf("\n");
		printf("%d\n", k);		
		for(int i = 1; i <= n; i++)
			printf("%d\n", color[i]);
		count++;	
	}		
	return 0;
}

这道题感觉怪怪的,没有思路。想到的是应该先选度数大的染色。如果度数大的先染色,度数小的点由于受到相邻点限制较少,较难出现到最后无法染色的情况。
如果先染了度数小的点,度数大的点到最后限制较大,更可能出现无法染色的情况。
就利用这个启发的信息,每次选择点进行染色,选择的标准是可选颜色最少的点,可选颜色为k-度数-已染色的相邻点。
感觉这种方法有问题,结果通过了。
看了别人的代码https://github.com/morris821028/UVa/blob/master/temp/1613%20-%20K-Graph%20Oddity.cpp
利用拓扑排序再选择和相邻点不同色进行染色,感觉也不太对。
这道题不太明白,以后再看。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值