Dfs/Bfs/记忆化搜索问题 | 问题集合

写在前面

动归和搜索似乎我打得特憋烂.

可能是因为搜索打的太少了???

然后之前做过的一些题我就不再写了,比如填涂颜色/海战啥的?

然后每一题打两种解法(:Dfs/Bfs

前提是在题目里两种都能A

然后重点是Cys好菜菜菜菜菜菜啊!!!!

 


 

 

P1596 湖计数

题目描述

Due to recent rains, water has pooled in various places in Farmer John's field, which is represented by a rectangle of N x M (1 <= N <= 100; 1 <= M <= 100) squares. Each square contains either water ('W') or dry land ('.'). Farmer John would like to figure out how many ponds have formed in his field. A pond is a connected set of squares with water in them, where a square is considered adjacent to all eight of its neighbors. Given a diagram of Farmer John's field, determine how many ponds he has.

由于近期的降雨,雨水汇集在农民约翰的田地不同的地方。我们用一个NxM(1<=N<=100;1<=M<=100)网格图表示。每个网格中有水('W') 或是旱地('.')。一个网格与其周围的八个网格相连,而一组相连的网格视为一个水坑。约翰想弄清楚他的田地已经形成了多少水坑。给出约翰田地的示意图,确定当中有多少水坑。

输入格式:

Line 1: Two space-separated integers: N and M * Lines 2..N+1: M characters per line representing one row of Farmer John's field. Each character is either 'W' or '.'. The characters do not have spaces between them.

第1行:两个空格隔开的整数:N 和 M 第2行到第N+1行:每行M个字符,每个字符是'W'或'.',它们表示网格图中的一排。字符之间没有空格。

输出格式:

Line 1: The number of ponds in Farmer John's field.

一行:水坑的数量

输入输出样例

输入样例#1:
10 12
W........WW.
.WWW.....WWW
....WW...WW.
.........WW.
.........W..
..W......W..
.W.W.....WW.
W.W.W.....W.
.W.W......W.
..W.......W.
输出样例#1:
3

解题思路

    •   似乎之前我已经做过很多类似这种的题了??似乎类似于细胞问题?
    •        Dfs/Bfs都可以
    •        每次去找一个W,找到后往他的八连通方向找是否还存在W
    •        如果存在继续拓展,每次把找到的W改成.
    •        这样我们只需要找到一个W,就可以把与这个W八连通(或者说他存在的水坑)全部改成.
    •        最后只需要统计找到W的次数
    •        W出现的次数就是水坑的个数,输出即可.

关于代码

 1 #include<cstdio>
 2 #include<cstdlib>
 3 #include<cstring>
 4 #include<iostream>
 5 #include<cmath>
 6 #include<algorithm>
 7 
 8 using namespace std;
 9 
10 char Map[111][111];
11 
12 void Dfs(int i , int j){
13     if (Map[i][j] == 0)
14         return;
15     Map[i][j] = 0;
16     Dfs(i+1 , j);
17     Dfs(i-1 , j);
18     Dfs(i , j+1);
19     Dfs(i , j-1);
20     Dfs(i+1 , j+1);
21     Dfs(i+1 , j-1);
22     Dfs(i-1 , j+1);
23     Dfs(i-1 , j-1);
24 }
25 int main(){
26     
27     ios :: sync_with_stdio(0);
28     int n , m ;
29     char a;
30     cin >> n >> m;
31     for (int i = 1;i <= n;++i)
32         for (int j = 1;j <= m;++j){
33             cin >> a;
34             if (a == '.') Map[i][j] = 0;
35                 else Map[i][j] = 1;
36         }
37     
38     int Ans_sum = 0;
39     for (int i = 1;i <= n;++i)
40         for (int j = 1;j <= m;++j){
41             if (Map[i][j] == 1)
42                 Ans_sum++;
43                 Dfs(i , j);
44             }
45             
46     cout << Ans_sum;
47 } 
湖计数/Dfs
 1 #include <cstdio>
 2 #include <cstdlib>
 3 #include <cstring>
 4 #include <iostream>
 5 #include <cmath>
 6 #include <algorithm>
 7 #include <queue>
 8 
 9 using namespace std;
10 
11 int Map[111][111];
12 int Book[111][111];
13 
14 queue <int> que;
15 
16 const int dx[8] = {0,0,1,-1,1,1,-1,-1},dy[8] = {1,-1,0,0,1,-1,1,-1}; 
17 
18 void Bfs(int x , int y){
19     Map[x][y] = 0;
20     Book[x][y] = 1;
21     que.push(x);
22     que.push(y);
23     int Ans_head , Ans_tail;
24     
25     while(!que.empty()){
26         Ans_head = que.front(),que.pop();
27         Ans_tail = que.front(),que.pop();
28         for (int i = 0;i < 8;++i){
29             int New_head = Ans_head+dx[i];
30             int New_tail = Ans_tail+dy[i];
31             if (Map[New_head][New_tail] && !Book[New_head][New_tail]){
32                 Map[New_head][New_tail] = 0;
33                 Book[New_head][New_tail] = 1;
34                 que.push(New_head);
35                 que.push(New_tail);
36             }
37         }
38     }
39 }
40 int main(){
41     
42     ios :: sync_with_stdio(0);
43     int n , m ;
44     char a;
45     cin >> n >> m;
46     for (int i = 1;i <= n;++i)
47         for (int j = 1;j <= m;++j){
48             cin >> a;
49             if (a == '.') Map[i][j] = 0;
50                 else Map[i][j] = 1;
51         }
52     
53     int Ans_sum = 0;
54     for (int i = 1;i <= n;++i)
55         for (int j = 1;j <= m;++j)
56             if (Map[i][j] == 1){
57                 Ans_sum++;
58                 Bfs(i , j);
59         }
60 
61 
62     cout << Ans_sum;    
63 } 
湖计数/Bfs

 

 

 


 

P1657 选书

题目描述

学校放寒假时,信息学奥赛辅导老师有1,2,3……x本书,要分给参加培训的x个人,每人只能选一本书,但是每人有两本喜欢的书。老师事先让每个人将自己喜欢的书填写在一张表上。然后根据他们填写的表来分配书本,希望设计一个程序帮助老师求出所有可能的分配方案,使每个学生都满意.

输入格式:

第1行:一个数x

第2行~第1+x行:每行两个数,表示ai喜欢的书的序号

输出格式:

只有一个数:总方案数total。

输入输出样例

输入样例#1:
5
1 3
4 5
2 5
1 4
3 5
输出样例#1:
2

解题思路

    •   生成全排列+可行性剪枝

  关于代码

#include<iostream>
#include<cstdio>
using namespace std;

int ans,n,love1,love2,like[21][21];
int choose[21];

void dfs(int n,int k){
    for(int i = 1; i <= n;i++) {
        if(!choose[i] && like[k][i]) {
            choose[i] = 1;
            if(k == n) ans++;
            else dfs(n , k+1);
            choose[i] = 0;
        }
    }
}

int main() {
    
    ios :: sync_with_stdio(0);
    cin >> n;
    for(int i = 1; i <= n; i++) {
        cin >> love1 >> love2;
        like[i][love1] = 1;
        like[i][love2] = 1;
    }
    
    dfs(n,1);
    
    cout << ans << endl;
    return 0;
}
选书/Dfs

 


 

 

P1294 高手去散步

题目背景

高手最近谈恋爱了。不过是单相思。“即使是单相思,也是完整的爱情”,高手从未放弃对它的追求。今天,这个阳光明媚的早晨,太阳从西边缓缓升起。于是它找到高手,希望在晨读开始之前和高手一起在鳌头山上一起散步。高手当然不会放弃这次梦寐以求的机会,他已经准备好了一切。

题目描述

鳌头山上有n个观景点,观景点两两之间有游步道共m条。高手的那个它,不喜欢太刺激的过程,因此那些没有路的观景点高手是不会选择去的。另外,她也不喜欢去同一个观景点一次以上。而高手想让他们在一起的路程最长(观景时它不会理高手),已知高手的穿梭机可以让他们在任意一个观景点出发,也在任意一个观景点结束。

输入输出格式

输入格式:

第一行,两个用空格隔开的整数n、m. 之后m行,为每条游步道的信息:两端观景点编号、长度。

输出格式:

一个整数,表示他们最长相伴的路程。

输入输出样例

输入样例#1: 
4 6
1 2 10
2 3 20
3 4 30
4 1 40
1 3 50
2 4 60
输出样例#1: 
150

说明

对于100%的数据:n≤20,m≤50,保证观景点两两之间不会有多条游步道连接.

 解题思路

  •   搜索入门大水题.
  •   第一次交错了/后来发现这是张无向图
  •        考虑到N比较小,我们可以直接搜索通过每个点能获得多大的恩爱(相伴)路程.
  •   最后只需要比较一下最大的恩爱路程即可.
  •        图的存储可以直接采用邻接矩阵.

 关于代码

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <algorithm>
 4 #include <cmath>
 5 #include <cstring>
 6 #include <queue>
 7 #define Inf 0x7fffff
 8 
 9 using namespace std;
10 
11 int Map[111][111] , Book[111] , Ans = 0;
12 
13 int Read()  {
14     int val = 0, opt = 1;
15     char ch;
16     while (!(isdigit( ch = getchar() ) || ch == '-'));
17     if (ch == '-') opt =-1;
18     else val = ch - '0';
19     while (isdigit( ch = getchar() )) (val *= 10) += ch - '0';
20     return val * opt;
21 }
22     
23 int N , M;
24     
25 int Dfs(int Now , int Wl){
26     
27     Ans = max(Ans , Wl);
28     for (register int i = 1 ; i <= N ; ++i){
29         if (!Book[i] && Map[Now][i]){
30             Book[i] = 1;
31             Dfs(i , Wl+Map[Now][i]);
32             Book[i] = 0;
33         }
34     }
35     
36     return 0;
37 }
38 int main(){
39     
40     ios :: sync_with_stdio(0);
41     
42     N = Read() , M = Read();
43     for (int i = 1 ; i <= M ; ++i){
44         int X , Y , Z;
45         X = Read() , Y = Read() , Z = Read();
46         Map[X][Y] = Map[Y][X] = Z;
47     }
48     
49     int Maxx = 0;
50     for (int i = 1 ; i <= N ; ++i){
51         Book[i] = 1;
52         Dfs(i , 0);
53         Maxx = max(Maxx , Ans);
54         
55         for (register int i = 1 ; i <= N ; ++i)
56             Book[i] = 0;
57     }
58         
59     cout << Maxx;
60     
61 }
高手去散步

 


 

 

P2853 [USACO06DEC]牛的野餐Cow Picnic

题目描述

The cows are having a picnic! Each of Farmer John's K (1 ≤ K ≤ 100) cows is grazing in one of N (1 ≤ N ≤ 1,000) pastures, conveniently numbered 1...N. The pastures are connected by M (1 ≤ M ≤ 10,000) one-way paths (no path connects a pasture to itself).

The cows want to gather in the same pasture for their picnic, but (because of the one-way paths) some cows may only be able to get to some pastures. Help the cows out by figuring out how many pastures are reachable by all cows, and hence are possible picnic locations.

K(1≤K≤100)只奶牛分散在N(1≤N≤1000)个牧场.现在她们要集中起来进餐.牧场之间有M(1≤M≤10000)条有向路连接,而且不存在起点和终点相同的有向路.她们进餐的地点必须是所有奶牛都可到达的地方.那么,有多少这样的牧场呢?

输入输出格式

输入格式:

 

Line 1: Three space-separated integers, respectively: K, N, and M

Lines 2..K+1: Line i+1 contains a single integer (1..N) which is the number of the pasture in which cow i is grazing.

Lines K+2..M+K+1: Each line contains two space-separated integers, respectively A and B (both 1..N and A != B), representing a one-way path from pasture A to pasture B.

 

输出格式:

 

Line 1: The single integer that is the number of pastures that are reachable by all cows via the one-way paths.

 

输入输出样例

输入样例#1:
2 4 4
2
3
1 2
1 4
2 3
3 4
输出样例#1:
2

说明

The cows can meet in pastures 3 or 4.

 解题思路

  •   由每只牛出发,Dfs遍历他所能到达的所有农场,给计数器++
  •        最后只需要统计有多少个农场农场符合 (计数器 == K)[即该农场满足K头牛都可以到达]

 关于代码

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <algorithm>
 4 #include <cmath>
 5 #include <cstring>
 6 #include <queue>
 7 #define Inf 0x7fffff
 8 
 9 using namespace std;
10 
11 int Read()  {
12     int val = 0, opt = 1;
13     char ch;
14     while (!(isdigit( ch = getchar() ) || ch == '-'));
15     if (ch == '-') opt =-1;
16     else val = ch - '0';
17     while (isdigit( ch = getchar() )) (val *= 10) += ch - '0';
18     return val * opt;
19 }
20     
21 int K , N , M;
22 int Home[11111] , Book[11111] , Yuns[11111] , Map[1111][1111];
23 
24 int Dfs(int X){
25     
26     Book[X]++;
27     Yuns[X] = 1;
28     for (register int i = 1 ; i <= N ; ++i){
29         if (Map[X][i] && !Yuns[i]){
30             Dfs(i);
31         }
32     }
33     
34     return 0;
35 }
36 
37 int main(){
38     
39     freopen("testdata.in" , "r" , stdin);
40     freopen("testdata.out" , "w" , stdout);
41     
42     ios :: sync_with_stdio(0);
43     
44     K = Read() , N = Read() , M = Read();
45     
46     for (int i = 1 ; i <= K ; ++i) Home[i] = Read();
47     for (int i = 1 ; i <= M ; ++i){
48         int X , Y;
49         X = Read();
50         Y = Read();
51         Map[X][Y] = 1;
52     } 
53 
54     for (int i = 1;i <= K; ++i){
55         
56         for (register int j = 1;j <= N ; ++j)
57             Yuns[j] = 0;
58             
59         Dfs(Home[i]);
60     }
61     
62     int Ans = 0;
63     for (int i = 1;i <= N; ++i)
64         if (Book[i] == K) Ans++;
65             
66     cout << Ans;
67 
68     return 0;
69 }
牛的野餐

 

posted @ 2017-08-19 16:08  Yuns's  阅读(1028)  评论(0编辑  收藏  举报