1. 程式人生 > >[蒟蒻的學習記錄]DFS的聯通塊與計數、剪枝

[蒟蒻的學習記錄]DFS的聯通塊與計數、剪枝

[蒟蒻的學習記錄]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 }//輸入 38
for(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 }