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 ` ', ` ' and ` '.
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 (3n9999, n is odd), m is the number of edges in the graph (2m100000). The following m lines describe edges of the graph, each edge is described by two integers ai, bi (1ai, bin, ai = 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 (1cik) 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
利用拓扑排序再选择和相邻点不同色进行染色,感觉也不太对。
这道题不太明白,以后再看。