CF
来源:互联网 发布:js使按钮点击事件失效 编辑:程序博客网 时间:2024/05/19 22:59
1.题目描述:
2.题意概述:
给你一个连通图,对它进行染色,某节点的颜色和他的相邻节点颜色不能相同,且对于每个父亲,它所有儿子的颜色都不能相同,问你最少需要多少颜色
3.解题思路:
很经典的染色问题,建图方法很多,可以vector也可以链式前向星,从任意节点开始dfs,每代记录和当代和父代的节点标号,这样可以保证当代的子代颜色与两者都不相同,接下来就是染色了,当时想的时候是vis记录颜色使用情况,现在想想大可不必,直接用cnt记录就好,注意的是,把当代所有儿子都染色完以后再去对儿子进行dfs。感觉bfs也是可以做的,以后再想咯。
更新:
这道题性质是对于每个父亲,所有儿子的颜色不同,而bfs性质又是要对父亲进行bfs,这样就不能保证当前是父亲,下一步对儿子染色时能有传递性了,除非另外记录上一步转移过来的颜色,最好做法是DFS。而如果只要求相邻节点颜色不同,则做法可以是bfs贪心地选颜色,具体题型参见UVA1613。
4.AC代码:
#include <bits/stdc++.h>#define INF 0x3f3f3f3f#define maxn 200100#define N 1111#define eps 1e-6#define pi acos(-1.0)#define e exp(1.0)using namespace std;const int mod = 1e9 + 7;typedef long long ll;typedef unsigned long long ull;vector<int> G[maxn];int color[maxn];void dfs(int cur, int pre){int cnt = 1;for (int i = 0; i < (int)G[cur].size(); i++)if (G[cur][i] != pre) //子父颜色不同{while (cnt == color[cur] || cnt == color[pre])cnt++;color[G[cur][i]] = cnt++; //染色}//先把当代儿子染完色再dfsfor (int i = 0; i < (int)G[cur].size(); i++)if (G[cur][i] != pre)dfs(G[cur][i], cur);}int main(){#ifndef ONLINE_JUDGEfreopen("in.txt", "r", stdin);freopen("out.txt", "w", stdout);long _begin_time = clock();#endifint n;while (~scanf("%d", &n)){for (int i = 1; i <= n; i++)G[i].clear();for (int i = 0; i < n - 1; i++){int u, v;scanf("%d%d", &u, &v);G[u].push_back(v);G[v].push_back(u);}memset(color, 0, sizeof(color));color[1] = 1;dfs(1, 0);int ans = 0;for (int i = 1; i <= n; i++)ans = max(ans, color[i]);printf("%d\n", ans);for (int i = 1; i <= n; i++)if (i == 1)printf("%d", color[i]);elseprintf(" %d", color[i]);puts("");}#ifndef ONLINE_JUDGElong _end_time = clock();printf("time = %ld ms.", _end_time - _begin_time);#endifreturn 0;}
0 0