给你一个连通图,对它进行染色,某节点的颜色和他的相邻节点颜色不能相同,且对于每个父亲,它所有儿子的颜色都不能相同,问你最少需要多少颜色
3.题解:
对于每个结点,通过在每次输入的过程中统计,得到其连接的点的个数并加上1得到的数,比较各个点的该数的最大值,即为我们所需要的最少颜色种类数。建立一个color数组,在DFS过程中给每个点涂色,保证其与父亲结点与祖父结点不同即可。
方法:链式前向星
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <stack>
#include "cmath"
#include "set"
using namespace std;
struct node{
int to,nex;
}edge[400005];
int color[400005];
int tep[400005];
int head[400005],cnt=1,num,sum;//head[i]代表 以i结点开始的第一条边的下标
void add(int u,int v){
edge[cnt].to=v;
edge[cnt].nex=head[u];
head[u]=cnt++;
}
void dfs(int t,int f){
int num=1;
for(int i=head[t];~i;i=edge[i].nex)
{
int v=edge[i].to;
if(v==f||color[v])continue; //这里的f代指父亲结点,用来防止搜回去
while(color[t]==num||color[f]==num)
num++;
color[v]=num++;
}
for(int i=head[t];~i;i=edge[i].nex)
{
int v=edge[i].to;
if(v==f)continue;
dfs(v,t);
}
}
int main(){
int n,m,i;
int mmax=0;
memset(head,-1,sizeof(head));
cin>>m;
for(i=0;i<m-1;i++){
int x,y;
cin>>x>>y;
add(x,y);
tep[x]++;
add(y,x);
tep[y]++;
mmax=max(mmax,tep[x]);
mmax=max(mmax,tep[y]);
}
sum=mmax;
color[1]=1;
dfs(1,0);
printf("%d\n",mmax+1);
for(int i=1;i<=m-1;i++)
printf("%d ",color[i]);
printf("%d\n",color[m]);
return 0;
}
BFS思路:由于BFS中无法在一次BFS中得到当前点以及当前点的父亲结点与祖父结点分别是多少,故增加一个fcolor数组用来记录该点父亲的颜色;
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <stack>
#include "cmath"
#include "set"
#include <queue>
using namespace std;
struct node{
int to,nex;
}edge[400005];
int color[400005];
int fcolor[400005];
int tep[200005];
int p[400005];
int head[400005],cnt=1,num,sum;//head[i]代表 以i结点开始的第一条边的下标
int vis[400005];
queue<int>tp;
void add(int u,int v){
edge[cnt].to=v;
edge[cnt].nex=head[u];
head[u]=cnt++;
}
int main(){
int n,m,i;
int mmax=0;
memset(head,-1,sizeof(head));
cin>>m;
for(i=0;i<m-1;i++){
int x,y;
cin>>x>>y;
add(x,y);
tep[x]++;
add(y,x);
tep[y]++;
mmax=max(mmax,tep[x]);
mmax=max(mmax,tep[y]);
}
vis[1]=1;
sum=mmax;
color[1]=1;
tp.push(1);
fcolor[1]=1;
while(!tp.empty())
{
int f=tp.front();
tp.pop();
num=1;
for(int i=head[f];~i;i=edge[i].nex)
{
int v=edge[i].to;
fcolor[v]=color[f];
if(vis[v])
continue;
while(num==color[f]||num==fcolor[f])
num++;
color[v]=num++;
vis[v]=1;
tp.push(v);
}
}
printf("%d\n",mmax+1);
for(int i=1;i<=m-1;i++)
printf("%d ",color[i]);
printf("%d\n",color[m]);
return 0;
}