Topic link: https://nanti.jisuanke.com/t/A1139
Question: Give an n*m 01 matrix, 1 means there is a bomb, 0 means No. After detonating a bomb, the bomb in the row and column will be detonated. Ask how many bombs to detonate manually to detonate all bombs.
Idea: Start thinking about direct violence with dfs, and the result is running out of time. There are three groups of examples. Later, Baidu searched it and found that it should be used and checked. First of all, I don't think about it. If a bomb detonates its line and column, then we can connect the x and y coordinates of the bomb. If the bomb appears in this line or column, then we can connect the x or y coordinates that didn't appear with the node in front. That's a very difficult problem. The x and y coordinates will repeat, so we can add an offset (+n) to the y coordinates, and that's the solution. Finally, just check it directly.
AC code
#include<iostream> #include<cstdio> using namespace std; const int maxn=1010; char a[maxn][maxn]; int f[maxn<<1]; int vis[maxn<<1]; void init(int n,int m) { for(int i=0; i<n+m; i++) { f[i]=i; vis[i]=0; } } int Find(int x) { if(x==f[x]) return x; else return f[x]=Find(f[x]); } void Merge(int x,int y) { int t1=Find(x),t2=Find(y); if(t1!=t2) { f[t1]=t2; } } int main() { int n,m; while(~scanf("%d%d",&n,&m)) { for(int i=0; i<n; i++) scanf("%s",a[i]); init(n,m); for(int i=0; i<n; i++) { for(int j=0; j<m; j++) { if(a[i][j]=='1') { Merge(i,j+n); } } } int ans=0; for(int i=0; i<n; i++) { for(int j=0; j<m; j++) { if(a[i][j]=='1') { int t=Find(i); if(!vis[t]) vis[t]=1,ans++; t=Find(j+n); if(!vis[t]) vis[t]=1,ans++; } } } printf("%d\n",ans); } return 0; }