BFS树就是通过bfs遍历一个图构成出来的树,特点就是在无权图上的非树边连接的两点一定在同一层(即深度相同)或者相邻的两层(即深度差的绝对值为1)。
原理:首先bfs树中每个点的深度就是这个点到树根的最短距离,这个想成权值为1的dijkstra就很容易理解,然后如果两个点隔了三层,而他们直接的边的权值为1,那么其中一个深度小的点就可以优化另一个深度大的点,所以这两个点深度绝对值最大为1.
H. Heat Pipes
这个题就是将所有的点的权值赋值为[a,b]中的一个数,使得任意一条边连着的两个点的权值的绝对值为1。
思路:明显染色问题,然后就是找如果奇偶奇偶这样染色,一个联通图的最大权值能染到多大,明显就是bfs树了,最大深度就是最大染色权值,因为bfs树如果根不同,那么最大深度可能不同,所以就n*n暴力bfs求最大深度即可,这个题的细节有点多,比如特判a==b,如果最大颜色超过了b就可以再从b到a循环,然后还要注意不连通。
#include<iostream>
#include<cstdio>
#include<vector>
#include<queue>
using namespace std;
const int MAX_N=2010;
vector<int>v[MAX_N],area[MAX_N];
int tot=0;
int col[MAX_N],deep[MAX_N];
int flag=1;
void dfs(int x){
int i;
if(!flag)
return ;
area[tot].push_back(x);
for(i=0;i<v[x].size();i++){
int y=v[x][i];
if(col[y]==col[x]){
flag=0;
return ;
}
if(col[y])
continue;
if(col[x]==1)
col[y]=2;
else
col[y]=1;
dfs(y);
}
}
bool vis[MAX_N];
int maxl;
void bfs(int x){
queue<int>q;
maxl=0;
q.push(x);
deep[x]=1;
vis[x]=true;
while(!q.empty()){
x=q.front();
q.pop();
maxl=max(maxl,deep[x]);
for(int i=0;i<v[x].size();i++){
int y=v[x][i];
if(vis[y])
continue;
vis[y]=true;
deep[y]=deep[x]+1;
q.push(y);
}
}
}
int res[MAX_N];
int a,b;
int max_deep[MAX_N];
int k[MAX_N];
int main(void){
int n,m,i,j,t,x,y;
int T;
cin>>T;
while(T--){
scanf("%d%d",&n,&m);
scanf("%d%d",&a,&b);
for(i=1;i<=n;i++){
col[i]=0;
v[i].clear();
//can[i]=0;
area[i].clear();
}
tot=0;
flag=1;
for(i=1;i<=m;i++){
scanf("%d%d",&x,&y);
v[x].push_back(y);
v[y].push_back(x);
}
if(a==b){
if(n==1){
printf("Yes\n%d\n",a);
}
else{
if(m==0){
printf("Yes\n");
for(i=1;i<=n;i++){
printf("%d",a);
if(i!=n)
printf(" ");
else
printf("\n");
}
}
else
printf("No\n");
}
continue;
}
for(i=1;i<=n;i++){
if(!flag)
break;
if(col[i])
continue;
col[i]=1;
tot++;
dfs(i);
}
if(!flag){
printf("No\n");
continue;
}
//printf("Yes\n");
int ff=0;
int sum=0;
for(i=1;i<=tot;i++){
int top=0;
int maxx;
for(j=0;j<area[i].size();j++){
int x=area[i][j];
for(t=0;t<area[i].size();t++)
vis[area[i][t]]=0;
bfs(x);
if(top<maxl){
top=maxl;
maxx=x;
}
}
//cout<<top<<" "<<maxx<<" !!\n";
for(j=0;j<area[i].size();j++)
vis[area[i][j]]=0;
bfs(maxx);
max_deep[i]=top;
sum+=top;
}
if(sum>=b-a+1)
ff=1;
//cout<<sum<<" sum\n";
if(!ff){
printf("No\n");
}
else{
printf("Yes\n");
int st=a;
int fl=1;
for(j=1;j<=sum;j++){
k[j]=st;
//cout<<j<<" "<<k[j]<<" !!\n";
if(fl){
st++;
if(st>b){
st=b-1;
fl=0;
}
}
else{
st--;
if(st<a){
st=a+1;
fl=1;
}
}
}
int down=0;
//cout<<tot<<" tot\n";
for(i=1;i<=tot;i++){
for(j=0;j<area[i].size();j++){
int x=area[i][j];
res[x]=k[deep[x]+down];
//cout<<x<<" "<<deep[x]<<"\n";
}
down+=max_deep[i];
}
for(i=1;i<=n;i++){
printf("%d",res[i]);
if(i!=n)
printf(" ");
else
printf("\n");
}
}
}
return 0;
}//rsb