这个多源bfs需要开两个队列,一个维护需要从什么节点开始扩展,另一个维护扩展的过程。
需要注意特判,否则当队列中只剩一种节点会出现有节点访问不到的情况,因为他们进了p队列
#include<bits/stdc++.h> using namespace std; struct node { int x,y,id,step; node(int a,int b,int c,int d) { x=a,y=b,id=c,step=d; } }; int n,m,p,a[10],ans[10]; int mv[4][2]={1,0,-1,0,0,1,0,-1}; char s[1005][1005]; int check(int x,int y) { if(x<1||x>n||y<1||y>m||s[x][y]!='.') return 0; return 1; } int pre=0; queue<node>q2,q; void bfs2(int tp) { while(!q2.empty()) { node e=q2.front();q2.pop(); for(int i=0;i<4;i++) { int x=e.x+mv[i][0]; int y=e.y+mv[i][1]; if(!check(x,y))continue; s[x][y]=e.id+'0'; if(e.step==1&&tp==0)//这里一定要加&&后面的特判,否则最后只剩下一种节点时就访问不完,剩下的节点会被q吃进去 q.push(node(x,y,e.id,a[e.id])); else q2.push(node(x,y,e.id,e.step-1)); } } } void bfs() { while(!q.empty()) { node e=q.front(); q.pop(); if(e.id==pre) { q2.push(e); continue; } pre=e.id; bfs2(0); q2.push(e); /* printf("*\n"); for(int i=1;i<=n;i++) { for(int j=1;j<=m;j++) printf("%c",s[i][j]); printf("\n"); }*/ } bfs2(1); } int main() { scanf("%d%d%d",&n,&m,&p); for(int i=1;i<=p;i++) scanf("%d",&a[i]); for(int i=1;i<=n;i++) scanf("%s",s[i]+1); for(int i=1;i<=p;i++) for(int j=1;j<=n;j++) for(int k=1;k<=m;k++) if(s[j][k]==i+'0') q.push(node(j,k,i,a[i])); bfs(); for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) if(s[i][j]>='1'&&s[i][j]<=p+'0') ans[s[i][j]-'0']++; /* printf("**\n"); for(int i=1;i<=n;i++) { for(int j=1;j<=m;j++) printf("%c",s[i][j]); printf("\n"); }*/ for(int i=1;i<p;i++)printf("%d ",ans[i]); printf("%d\n",ans[p]); }