F - Super Jaber CodeForces - 1301F

 #include<bits/stdc++.h>
using namespace std;
const int N = 1010;
int a[N][N],dis[50][N][N],vis[N][N],used[50];//dis[k][x] 表示第 k 类颜色的所有点到 x 的最短距离
//used表示颜色是否用过
 
int n,m,k;
int mov[4][2]={{0,1},{0,-1},{1,0},{-1,0}};
struct node{//point
 int x,y;
 node(int _x,int _y){
  x=_x,y=_y;
 }
};
queue<node> q;
vector<node> v[50];
void bfs(int id){
 
 memset(vis,0,sizeof (vis));
 memset(used,0,sizeof(used));
 while(!q.empty()){
  q.pop();
 }                     //多组数据初始化 
 for(int i=0;i<v[id].size();i++){
  int x=v[id][i].x,y=v[id][i].y;
  q.push(node(x,y));
  vis[x][y]=1;
  dis[id][x][y]=0;
 }
 used[id]=1;
 while(!q.empty()){
  node u=q.front();
  q.pop();
  int x=u.x,y=u.y,col=a[x][y];
  //-----------------------------
  if(!used[col]){
   used[col]=1;
   for(int i=0;i<v[col].size();i++){
    int xx=v[col][i].x,yy=v[col][i].y;
    if(vis[xx][yy]) continue;
    q.push(node(xx,yy));//不同颜色的跳跃过程 
    vis[xx][yy]=1;
    dis[id][xx][yy]=dis[id][x][y]+1;
   }
  }
  //-------------------------
  for(int i=0;i<4;i++){//求曼哈顿距离 
   int xx=x+mov[i][0],yy=y+mov[i][1];
   if(xx>0&&xx<=n&&yy>0&&yy<=m&&!vis[xx][yy]){
    q.push(node(xx,yy));
    vis[xx][yy]=1;
    dis[id][xx][yy]=dis[id][x][y]+1;
   }
  }
  
 }
 
}
int main(){
 cin>>n>>m>>k;
 for(int i=1;i<=n;i++){
  for(int j=1;j<=m;j++){
   scanf("%d",&a[i][j]);//初始化颜色图 
   v[a[i][j]].push_back(node(i,j));//分类颜色 
  }
 }
 for(int i=1;i<=k;i++) {
  bfs(i);
 }//依照颜色进行bfs 
 int t;
 cin>>t;
 while(t--){
  int r1,c1,r2,c2;
  scanf("%d%d%d%d",&r1,&c1,&r2,&c2);
  int ans=abs(r1-r2)+abs(c1-c2);
  for(int i=1;i<=k;i++){
   ans=min(ans,dis[i][r1][c1]+dis[i][r2][c2]+1);
  }
  printf("%d\n",ans);
 }
 
 return 0;
} 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值