BFS樹

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
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章