2道题目都差不多,就是问和相邻所有点都有相同数据相连的作为一个联通快,问有多少个连通块
因为最近对搜索题目很是畏惧,总是需要看别人代码才能上手,就先拿这两道简单的dfs题目来练练手,顺便理一理dfs的思路,分析清楚dfs的退出递归的条件和什么时候进行递归调用是至关重要的,这两道题目不涉及回溯,对于需要回溯的题目也要清楚分析,找到回溯条件,在对一个新的状态dfs时,后面加上回溯的语句
HDU1241代码:
1 #include <cstdio> 2 #include <cstring> 3 #include <iostream> 4 using namespace std; 5 6 int n,m,ans; 7 int visit[102][102],dir[8][2] = {{1,0},{-1,0},{0,1},{0,-1},{1,1},{1,-1},{-1,1},{-1,-1}}; 8 char mat[102][102]; 9 10 void dfs(int a,int b) 11 { 12 visit[a][b] = 1; 13 for(int i=0;i<8;i++){ 14 int xx = a+dir[i][0]; 15 int yy = b+dir[i][1]; 16 if(xx>=0&&xx<n&&yy>=0&&yy<m&&mat[xx][yy]=='@'){ 17 if(!visit[xx][yy]) 18 dfs(xx,yy); 19 } 20 } 21 } 22 int main() 23 { 24 while(~scanf("%d%d",&n,&m)){ 25 if(n==0&&m==0) break; 26 27 for(int i=0;i<n;i++){ 28 for(int j=0;j<m;j++) 29 cin>>mat[i][j]; 30 } 31 32 memset(visit,0,sizeof(visit)); 33 ans = 0; 34 35 for(int i=0;i<n;i++) 36 { 37 for(int j=0;j<m;j++) 38 if(!visit[i][j]&&mat[i][j] == '@') 39 { 40 dfs(i,j); 41 ans++; 42 } 43 } 44 45 printf("%d ",ans); 46 } 47 return 0; 48 }
POJ2386代码:
1 #include <cstdio> 2 #include <cstring> 3 4 using namespace std; 5 6 #define N 102 7 8 int n,m,ans; 9 int visit[N][N],dir[8][2] = {{1,0},{-1,0},{0,1},{0,-1},{1,1},{1,-1},{-1,1},{-1,-1}}; 10 char mat[N][N]; 11 12 void dfs(int x,int y) 13 { 14 visit[x][y]=1; 15 for(int i=0;i<8;i++){ 16 int xx=x+dir[i][0]; 17 int yy=y+dir[i][1]; 18 if(xx>=0&&x<n&&yy>=0&&yy<m&&mat[xx][yy]=='W'&&!visit[xx][yy]) 19 dfs(xx,yy); 20 } 21 } 22 23 int main() 24 { 25 while(~scanf("%d%d",&n,&m)){ 26 for(int i=0;i<n;i++) 27 scanf("%s",mat[i]); 28 29 memset(visit,0,sizeof(visit)); 30 ans=0; 31 32 for(int i = 0 ;i<n;i++) 33 for(int j=0;j<m;j++){ 34 if(mat[i][j] == 'W'&&!visit[i][j]) 35 { 36 dfs(i,j); 37 ans++; 38 } 39 } 40 41 printf("%d ",ans); 42 } 43 return 0; 44 }