codeforces#375(div.2)723D - Lakes in Berland dfs+bfs

来源:互联网 发布:python电影推荐系统 编辑:程序博客网 时间:2024/05/17 23:56

题意:给你一张n×m的图,点代表水,星代表地,当水连在一块时,称为湖,但是,若湖中有水在边界上,则不算它是湖,现在要求你去掉x个湖,并用地将其填上,使原图剩下k个湖,输出你最少需要多少个单位的地,并且输出你填补过的图。


比赛的时候没过,好菜呀。


思路:首先定义两个数组bfs_vis,dfs_vis,分别记录bfs和dfs的访问状况,定义flag,true代表一块区域属于湖,false代表一块区域不属于湖,vector[top]记录第top个湖内的点的情况,top初始化为0。

然后说下dfs的思路,从一个'.'点出发,并且只走'.',若其走到了边界上,则标记flag为false,此时并不结束dfs,而是继续走,将这一整块水域全部走完,并且dfs_vis都标记为true代表已经走过。相反,若走不到边界上,则一定能走完这个水域,flag为true,在dfs的同时,将走过的每一个点都装入vec[top]。当dfs完成后,若flag为false,则清空vec[top],否则top++,进入下个vec[top]记录新的湖。

然后说bfs,就是从(1,1)开始遍历,若找到一个点'.',并且其dfs_vis为false的话,说明它没有在dfs中被访问过,则对其进行dfs,当dfs完成后,若flag为true,说明这个点所在水域为湖,则记录它的大小和序号。

最后只要对这些湖的大小进行升序排序,并且相应的将其中的点填上就行了。


为什么这么强调dfs_vis呢,因为我就坑在这啦,最开始的时候,我在dfs中一旦发现某个点走到了边界就立即停止dfs并返回false,这样出现的问题就是当一个水域只有一个点在边界的时候,假如我们第一次就dfs到了改点,那么就相当于将其变成了陆地。则其剩下的水域在下一次dfs的时候就会被判定为一个湖。


代码:

#include<bits/stdc++.h>#define MEM(a,x) memset(a,x,sizeof(a));#define MEMINF(a) memset(a,0x3f,sizeof(a));using namespace std;typedef long long LL;const int MAXN=4000;const int INF=0x3f3f3f3f;const int MOD=1000000007;int n,m,k;char mp[MAXN][MAXN];int dx[]={0,0,1,-1};int dy[]={1,-1,0,0};int top;struct node {  int x,y;};bool bfs_vis[MAXN][MAXN];bool dfs_vis[MAXN][MAXN];bool cmp(node a,node b) {  return a.x<b.x;}vector<node>que;queue<node>q;vector<node> vec[MAXN];bool flag;void dfs(node u) {  vec[top].push_back(u);  dfs_vis[u.x][u.y]=1;  if (u.x==1||u.x==n||u.y==1||u.y==m) flag=false;  for (int i=0; i<4; ++i) {    node v=u;    v.x+=dx[i];    v.y+=dy[i];    if (dfs_vis[v.x][v.y])continue;    if (mp[v.x][v.y]!='.') continue;    //printf("%d %d\n",v.x,v.y);    if (v.x==1||v.x==n||v.y==1||v.y==m) flag=false;    dfs(v);  }}void bfs(){  node u;  u.x=1,u.y=1;  q.push(u);  bfs_vis[1][1]=1;  MEM(bfs_vis,0);  while(!q.empty()) {    node no=q.front();    q.pop();    //printf("m %c %d\n",mp[4][3],!dfs_vis[4][3]);    if (mp[no.x][no.y]=='.'&&!dfs_vis[no.x][no.y]) {      flag=true;      //puts("-----");      dfs(no);      if (flag) {       //printf("no:%d %d\n",no.x,no.y);        //puts("*****");        node lal;        lal.x=vec[top].size();        lal.y=top;        que.push_back(lal);        top++;      }      else {        vec[top].clear();      }    }    for (int i=0; i<4; ++i) {      node v=no;      v.x+=dx[i];      v.y+=dy[i];      if (bfs_vis[v.x][v.y])continue;      if (v.x<1||v.x>n||v.y<1||v.y>m) continue;      q.push(v);      bfs_vis[v.x][v.y]=1;    }  }}      int main() {  scanf("%d %d %d",&n,&m,&k);  top=0;  for (int i=1; i<=n; ++i) {    scanf("%s",mp[i]+1);  }  bfs();  //printf("MAP%ld\n",que.size());  int sum=0;  sort(que.begin(),que.end(),cmp);  for (auto i=0; i<top-k; ++i) {    sum+=que[i].x;    int num=que[i].y;    for (int it=0;it<vec[num].size(); ++it) {      int x=vec[num][it].x;      int y=vec[num][it].y;     mp[x][y]='*';    }  }  printf("%d\n",sum);  for (int i=1; i<=n; ++i)    puts(mp[i]+1);}


0 0
原创粉丝点击