zstu 4215 多起点bfs
input
n m 1<=n,m<=1000
n*m的地图,全为大写字母
7 10 WWWWWCCDEW WWWWCCEEEW WTWWWCCCCW WWFFFFFFWW WWFAAAAFWW WWFABCAFFW WWFAAAAFWW
output
从W到每种字母跨过最少的其它字母个数,如从W到A只跨过一种字母F
A 1 B 2 C 0 D 1 E 0 F 0 T 0
做法:把每个W的连通块当成起点依次进队进行bfs
1 #include <bits/stdc++.h> 2 #define MAX 1000000 3 #define LL long long 4 using namespace std; 5 int cas=1,T,n,m,v[1010][1010],idn,mind[30],idp[MAX+10][2];//idp表示连通块起点 6 char s[1010][1010],id[MAX+10]; 7 int vis[MAX+10]; 8 void dfs(int x,int y,char& c,int &id)//连通块标id 9 { 10 if(x>=n||y>=m||x<0||y<0||v[x][y]!=-1||s[x][y]!=c) return; 11 v[x][y]=id; 12 dfs(x+1,y,c,id); 13 dfs(x-1,y,c,id); 14 dfs(x,y+1,c,id); 15 dfs(x,y-1,c,id); 16 dfs(x+1,y+1,c,id); 17 dfs(x-1,y-1,c,id); 18 dfs(x+1,y-1,c,id); 19 dfs(x-1,y+1,c,id); 20 } 21 queue<int>q[2]; 22 void dfs(int x,int y,int &k,int d)//查找相邻接的连通块 23 { 24 if(x<0||y<0||x>=n||y>=m) return; 25 if(v[x][y]!=k) { q[d].push(v[x][y]);return; }//入队列 26 if(!s[x][y]) return; 27 s[x][y]=0; 28 dfs(x+1,y,k,d); 29 dfs(x-1,y,k,d); 30 dfs(x,y+1,k,d); 31 dfs(x,y-1,k,d); 32 dfs(x+1,y+1,k,d); 33 dfs(x-1,y-1,k,d); 34 dfs(x+1,y-1,k,d); 35 dfs(x-1,y+1,k,d); 36 } 37 void bfs() 38 { 39 memset(vis,-1,sizeof(vis)); 40 int d=0,step=1; 41 while(!q[0].empty()) q[0].pop(); 42 while(!q[1].empty()) q[1].pop(); 43 for(int i=0;i<n;i++) 44 for(int j=0;j<m;j++) 45 if(s[i][j]&&s[i][j]=='W') { dfs(i,j,v[i][j],d);vis[v[i][j]]=0; } 46 while(!q[d].empty())//两个队列bfs,一个队列是一步 47 { 48 while(!q[d].empty()) 49 { 50 int u=q[d].front();q[d].pop(); 51 if(vis[u]!=-1) continue; //标记 52 dfs(idp[u][0],idp[u][1],u,d^1); 53 vis[u]=step; 54 } 55 step++; 56 d^=1; 57 } 58 // for(int i=0;i<idn;i++) printf("%d %c %d\n",i,id[i],vis[i]); 59 } 60 void process() 61 { 62 idn=0; 63 for(int i=0;i<n;i++) //给每个连通块标>=0的id 64 for(int j=0;j<m;j++) 65 if(v[i][j]==-1) { dfs(i,j,s[i][j],idn);idp[idn][0]=i;idp[idn][1]=j;id[idn++]=s[i][j]; } 66 // for(int i=0;i<n;i++,printf("\n")) for(int j=0;j<m;j++) printf("%02d ",v[i][j]); 67 } 68 int main() 69 { 70 // freopen("in","r",stdin); 71 //scanf("%d",&T); 72 while(scanf("%d%d",&n,&m)==2) 73 { 74 for(int i=0;i<n;i++) { scanf("%s",s[i]);memset(v[i],-1,sizeof(int)*m); } //input 75 process(); 76 bfs(); 77 for(int i=0;i<26;i++) mind[i]=MAX; //查找每个大写字母的最小值 78 for(int i=0;i<idn;i++) mind[id[i]-'A']=min(mind[id[i]-'A'],vis[i]); 79 for(int i=0;i<26;i++) if(mind[i]&&mind[i]<MAX) printf("%c %d\n",i+'A',mind[i]-1); 80 } 81 //printf("time=%.3lf\n",(double)clock()/CLOCKS_PER_SEC); 82 return 0; 83 } 84 /************************************************************** 85 Problem: 4215 86 User: 15xss282 87 Language: C++ 88 Result: Accepted 89 Time:364 ms 90 Memory:21028 kb 91 ****************************************************************/