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