[蒟蒻的學習記錄]DFS的聯通塊與計數、剪枝
阿新 • • 發佈:2018-12-16
[蒟蒻的學習記錄]DFS的聯通塊與計數、剪枝
DFS的聯通塊問題(模板)
1 #include <bits/stdc++.h> 2 using namespace std; 3 const int maxn=1000; 4 int n,m; 5 //地圖尺寸 6 int maap[maxn+10][maxn+10]; 7 //查詢零一地圖中的1聯通塊個數 8 bool vis[maxn+10][maxn+10]; 9 int direx[]={1,-1,0,0}; 10 int direy[]={0,0,1,-1}; 11 //四向聯通 12 void dfs(int x,int y)13 { 14 vis[x][y]=true; 15 //打訪問標記 16 for(int i=0;i<4;i++) 17 { 18 int x_now=x+direx[i]; 19 int y_now=y+direy[i]; 20 if(x_now>=1&&x_now<=n&&y_now>=1&&y_now<=m&&!vis[x_now][y_now]&&maap[x_now][y_now]==1) 21 //不超邊界未訪問不為0 22 { 23 dfs(x_now,y_now); 24 } 25 } 26 } 27 int main() 28 { 29 int cnt=0; 30 cin>>n>>m; 31 for(int i=1;i<=n;i++) 32 { 33 for(int j=1;j<=m;j++) 34 { 35 cin>>maap[i][j]; 36 } 37 }//輸入 38for(int i=1;i<=n;i++) 39 { 40 for(int j=1;j<=m;j++) 41 { 42 if(maap[i][j]==1&&!vis[i][j]) 43 { 44 dfs(i,j); 45 cnt++; 46 } 47 } 48 }//dfs計數模組,不能把它直接加在輸入環節!! 49 //不然地圖都沒輸入完求個啥的聯塊!! 50 cout<<cnt<<endl; 51 }
DFS的計步(最短路)問題(模板)
1 #include <bits/stdc++.h> 2 using namespace std; 3 const int maxn=1000; 4 int maap[maxn+10][maxn+10]; 5 //零一迷宮的最短路問題(不剪枝優化) 6 //0是障礙,1是道路 7 bool vis[maxn+10][maxn+10]; 8 //訪問標記 9 int direx[]={0,1,0,-1}; 10 int direy[]={1,0,-1,0}; 11 //四向聯通 12 int n,m; 13 //地圖尺寸 14 int stx,sty,edx,edy; 15 //起點終點座標 16 int minstep; 17 //最少步數(初始化為矩陣內遍歷步數) 18 void dfs(int x, int y, int step) 19 { 20 vis[x][y] = true; 21 //打訪問標記 22 if(x == edx && y == edy) 23 //到達終點 24 { 25 minstep=min(minstep,step); 26 //打擂臺 27 return; 28 } 29 for(int i = 0; i < 4; i++) 30 { 31 int x_now = x + direx[i]; 32 int y_now = y + direy[i]; 33 if(1<=x_now&&x_now<=n&&1<=y_now&&y_now<=m&&vis[x_now][y_now]==0&&maap[x_now][y_now]) 34 //不出界未訪問不撞牆判定 35 { 36 dfs(x_now, y_now, step+1); 37 } 38 } 39 vis[x][y] = false;//回溯 40 } 41 int main() 42 { 43 cin>>n>>m; 44 minstep=n*m; 45 for(int i=1;i<=n;i++) 46 { 47 for(int j=1;j<=m;j++) 48 { 49 cin>>maap[i][j]; 50 } 51 } 52 cin>>stx>>sty>>edx>>edy;//輸入 53 dfs(stx,sty,0); 54 //深搜 55 cout<<minstep<<endl; 56 return 0; 57 }
DFS剪枝優化計步(模板)
1 void dfs(int x, int y, int step) 2 { 3 /************唯一的變化*************/ 4 if(step>minstep) 5 { 6 return; 7 } 8 /**********************************/ 9 vis[x][y] = true; 10 //打訪問標記 11 if(x == edx && y == edy) 12 //到達終點 13 { 14 minstep=min(minstep,step); 15 //打擂臺 16 return; 17 } 18 for(int i = 0; i < 4; i++) 19 { 20 int x_now = x + direx[i]; 21 int y_now = y + direy[i]; 22 if(1<=x_now&&x_now<=n&&1<=y_now&&y_now<=m&&vis[x_now][y_now]==0&&maap[x_now][y_now]) 23 //不出界未訪問不撞牆判定 24 { 25 dfs(x_now, y_now, step+1); 26 } 27 } 28 vis[x][y] = false;//回溯 29 }