**Algorithm: parallel search set**
Difficulty: (NOIP -)
In fact, this problem can be directly bfs, but the search is skilled, can not be violent search!
First of all, it's easy to find out that it must be the optimal solution to build water pumps only in all of our own cities. Therefore, according to this property, we come to bfs
Rank your city by height. The premise that you don't need to build a city is that you can get to a city where water pumps have been built through a path whose height is less than or equal to his!
Tip: instead of deep search, you can prevent unclear backtracking. If you return directly in the loop, you can end the whole function!
1.0 false greed + dfs!
#include <cstdio> #include <iostream> #include <cstring> #include <cmath> #include <algorithm> #include <cstdlib> #include <queue> #define N 1005 using namespace std; int mapp[N][N]; int vis[N][N]; int viss[N][N]; int fa[N]; struct node { int x,y; int val; }poi[N*N]; int findf(int x) { if(x==fa[x]) return x; return fa[x]=findf(fa[x]); } int cmp(node a,node b) { return a.val<b.val; } int fla,ans,cnt,n,m; int dx[6]={0,1,-1,0,0}; int dy[6]={0,0,0,1,-1}; void bfs(int x,int y) { if(fla==cnt) { printf("%d\n",ans); exit(0); } if(x<=0||y<=0||x>n||y>m) return; if(viss[x][y]) return; if(vis[x][y]) { fla++; } viss[x][y]=1; for(int i = 1;i <= 4;i++) { if(x+dx[i]<=0||y+dy[i]<=0||x+dx[i]>n||y+dy[i]>m) continue; if(mapp[x][y]>mapp[x+dx[i]][y+dy[i]]) continue; bfs(x+dx[i],y+dy[i]); } } int main() { scanf("%d%d",&n,&m); //memset(mapp,0x3f3f3f3f,sizeof(mapp)); for(int i = 1;i <= n;i++) { for(int j = 1;j <= m;j++) { int he; scanf("%d",&he); if(he>0) { vis[i][j]=1; ++cnt; poi[cnt].x=i; poi[cnt].y=j; poi[cnt].val=he; mapp[i][j]=he; }else { mapp[i][j]=-he; } } } sort(poi+1,poi+1+cnt,cmp); for(int i = 1;i <= cnt;i++) { if(viss[poi[i].x][poi[i].y]) continue; ans++; bfs(poi[i].x,poi[i].y); } if(fla==cnt) { printf("%d\n",ans); exit(0); } return 0 ; } /*/ 3 2 -1 -1 -3 -2 9 100 6 -4 -5 */
2.0 bfs(AC)
#include <cstdio> #include <iostream> #include <cstring> #include <cmath> #include <algorithm> #include <cstdlib> #include <queue> #define N 1005 using namespace std; int vis[N][N],viss[N][N]; int mapp[N][N]; int dx[6]={-1,1,0,0},dy[6]={0,0,-1,1}; struct node { int x;int y;int he; }poi[N*N]; int cmp(node a,node b) { return a.he<b.he; } int ctt; int qx[N*N],qy[N*N],bo[N][N]; int pre=0; int bfs(int x,int y) { pre++; bo[x][y]=pre; qx[1]=x,qy[1]=y; int h=1,t=1,nx,ny,nh=mapp[x][y]; while(h<=t) { nx=qx[h]; ny=qy[h++]; for(int i = 0;i < 4;i++) { int xx=nx+dx[i],yy=ny+dy[i]; if(vis[xx][yy]&&bo[xx][yy]!=pre&&mapp[xx][yy]<=nh) { bo[xx][yy]=pre; qx[++t]=xx;qy[t]=yy; if(viss[xx][yy]) return 1; } } } return 0; } int main() { int n,m; scanf("%d%d",&n,&m); int cnt=0; for(int i = 1;i <= n;i++) { for(int j = 1;j <= m;j++) { vis[i][j]=1; int x; scanf("%d",&x); if(x>0) { mapp[i][j]=x; poi[++cnt].x=i; poi[cnt].y=j; poi[cnt].he=x; bo[i][j]=1; }else mapp[i][j]=-x; } } sort(poi+1,poi+1+cnt,cmp); int ans=0; for(int i = 1;i <= cnt;i++) { if(!bfs(poi[i].x,poi[i].y)) ans++; viss[poi[i].x][poi[i].y]=1; } printf("%d\n",ans); return 0 ; }