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
",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("
")) 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
",i+'A',mind[i]-1);
80     }
81     //printf("time=%.3lf
",(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 ****************************************************************/
View Code
原文地址:https://www.cnblogs.com/cdyboke/p/5064677.html