http://codeforces.com/contest/782/problem/C
题意:给一棵树染最少的颜色,使得相邻距离为2的点都是不同的颜色,问最少是多少种颜色并输出每个点的颜色。
思路:比赛的时候没想到是找度最大的一个点并+1就是总颜色数,一直想怎么构造。
最后的总颜色数是度最大的一个点的度数+1。因为我们选的这个点到儿子的距离为1,因此其某一个儿子到另一个儿子的距离为2,就是这些儿子都要染成不同的颜色,+1是因为自己本身也要是不同的颜色。
然后确定了总颜色数,就可以DFS染色了。
参数记录一个上上个结点和上个结点染了什么颜色,只要儿子染成不同的就可以了,注意儿子之间颜色也要不同。
1 #include <bits/stdc++.h> 2 using namespace std; 3 #define N 200010 4 struct Edge { 5 int v, nxt; 6 } edge[N*2]; 7 int head[N], tot, col[N], deg[N], ans; 8 9 void Add(int u, int v) { 10 edge[tot] = (Edge) {v, head[u]}; head[u] = tot++; 11 edge[tot] = (Edge) {u, head[v]}; head[v] = tot++; 12 } 13 14 void dfs(int u, int fa, int c1, int c2) { 15 int c = 1; 16 for(int i = head[u]; ~i; i = edge[i].nxt) { 17 int v = edge[i].v; 18 if(v == fa) continue; 19 if(col[v]) continue; 20 for( ; c <= ans; c++) 21 if(c != c1 && c != c2) { 22 col[v] = c; break; 23 } 24 c++; 25 dfs(v, u, col[v], col[u]); 26 } 27 } 28 29 int main() { 30 int n; 31 scanf("%d", &n); 32 memset(head, -1, sizeof(head)); 33 for(int i = 1; i < n; i++) { 34 int u, v; 35 scanf("%d%d", &u, &v); 36 deg[u]++; deg[v]++; 37 Add(u, v); 38 } 39 ans = 0; 40 for(int i = 1; i <= n; i++) if(ans < deg[i] + 1) ans = deg[i] + 1; 41 42 col[1] = 1; 43 dfs(1, -1, 1, -1); 44 printf("%d\n", ans); 45 for(int i = 1; i <= n; i++) printf("%d ", col[i]); 46 return 0; 47 }
来源:https://www.cnblogs.com/fightfordream/p/6509988.html