题意:
有一颗n个节点的树,进行有限制染色,问染色的最少颜色数,以及每个点的颜色(从1标号,标号不能超过颜色数). 限制:相邻三个点的颜色不能相同.
输入格式:
第一行一个n, 接下来n-1行<x,y>,表示x与y之间有一条连边.
输出格式:
第一行一个数,为最小颜色数. 接下来n个数,为[1,n]的点的颜色.
数据范围:
n:[3,2e5]
首先需要明确一点,相邻三个点颜色不相同的最小颜色数是:度数最高的点的度数加一。明确了这个条件后就是单纯的进行dfs,然后根据相邻三个点颜色不同进行染色了。
代码:
#include <cstdio>
#include <vector>
#include <algorithm>
using namespace std;
vector<int>G[1008611];
int deg[10086111],maxx=-1;
int col[10086111];
void dfs(int u,int fa,int c1,int c2)
{
int i,v,j=1;
for(i=0;i<G[u].size();i++)
{
v=G[u][i];
if(v==fa)
continue;
for(;j<=maxx;j++)
{
if(j!=c1&&j!=c2)
{
col[v]=j;
break;
}
}
j++;
dfs(v,u,col[v],col[u]);
}
}
int main()
{
int n,i,x,y;
scanf("%d",&n);
for(i=1;i<n;i++)
{
scanf("%d%d",&x,&y);
G[x].push_back(y);
G[y].push_back(x);
deg[x]++;
deg[y]++;
maxx=max(deg[x],maxx);
maxx=max(deg[y],maxx);
}
col[1]=1;
maxx++;
dfs(1,-1,col[1],0);
printf("%d\n",maxx);
for(i=1;i<n;i++)
{
printf("%d ",col[i]);
}
printf("%d\n",col[n]);
return 0;
}