计蒜客 引爆炸弹(DFS、并查集)

在一个 n×m 的方格地图上,某些方格上放置着炸弹。手动引爆一个炸弹以后,炸弹会把炸弹所在的行和列上的所有炸弹引爆,被引爆的炸弹又能引爆其他炸弹,这样连锁下去。

 

现在为了引爆地图上的所有炸弹,需要手动引爆其中一些炸弹,为了把危险程度降到最低,请算出最少手动引爆多少个炸弹可以把地图上的所有炸弹引爆。

输入格式
第一行输两个整数 n,m,用空格隔开。

接下来 n 行,每行输入一个长度为 m 的字符串,表示地图信息。0表示没有炸弹,1表示炸弹。

数据约定:

对于 60% 的数据:1≤n,m≤100;

对于 100% 的数据:1≤n,m≤1000;

数据量比较大,不建议用cin输入。

输出格式
输出一个整数,表示最少需要手动引爆的炸弹数。

样例输入

5 5
00010
00010
01001
10001
01000


样例输出

2 

方法一(DFS):

 1 #include <stdio.h>
 2 #include <string.h>
 3 #include <iostream>
 4 #include <string>
 5 #include <math.h>
 6 #include <algorithm>
 7 #include <vector>
 8 #include <stack>
 9 #include <queue>
10 #include <set>
11 #include <map>
12 #include <sstream>
13 const int INF=0x3f3f3f3f;
14 typedef long long LL;
15 const int mod=1e9+7;
16 const double PI = acos(-1);
17 const double eps =1e-8;
18 #define Bug cout<<"---------------------"<<endl
19 const int maxn=1e5+10;
20 using namespace std;
21 
22 char G[1005][1005];
23 int n,m,ans; 
24 int vx[1005],vy[1005];//vx[i]表示第i行有没有引爆过,vy[i]表示第i列有没有引爆过 
25 
26 void DFS(int x,int y)
27 {
28     G[x][y]='0';
29     if(!vx[x])
30     {
31         vx[x]=1;
32         for(int i=1;i<=m;i++)
33         {
34             if(G[x][i]=='1')
35                 DFS(x,i);
36         }
37     }
38     if(!vy[y])
39     {
40         vy[y]=1;
41         for(int i=1;i<=n;i++)
42         {
43             if(G[i][y]=='1')
44                 DFS(i,y);
45         }
46     }
47 }
48 
49 int main()
50 {
51     #ifdef DEBUG
52     freopen("sample.txt","r",stdin);
53     #endif
54     ios_base::sync_with_stdio(false);
55     cin.tie(NULL);
56     
57     scanf("%d %d",&n,&m);
58     for(int i=1;i<=n;i++)
59         scanf("%s",G[i]);
60     for(int i=1;i<=n;i++)
61     {
62         for(int j=1;j<=m;j++)
63         {
64             if(G[i][j]=='1')
65             {
66                 DFS(i,j);
67                 ans++;
68             }
69         }
70     }
71     printf("%d
",ans);
72     return 0;
73 }

方法二(并查集):

使用并查集相较DFS比较麻烦,类比连通块,将相互联通的炸弹划到同一个集合。

这里的思路是将行列存到同一个数组中,将某一个炸弹的行列划分到一个集合,将同一行或者同一列划分到同一集合,最后存在多少个集合即为结果。

原文地址:https://www.cnblogs.com/jiamian/p/12175878.html