【BFS】【map】hdu5925 Coconuts

题意:一张n*m的网格图(n和m可以达到10^9),其中K个点是障碍物(不超过200个),问你没有被障碍物占据的点形成了几个连通块?并且输出各个连通块的大小。

容易证明,大小超过40000的连通块最多只有一个。于是可以从每个与障碍物邻接的非障碍点出发bfs,限制步数不超过40000,这样就可以找到所有小的连通块。最后如果n*m-K-小的连通块的总大小不等于0,则剩下的就是那个大的连通块的大小。

用map打标记进行判重。

#include<cstdio>
#include<queue>
#include<set>
#include<vector>
#include<map>
#include<algorithm>
using namespace std;
typedef long long ll;
typedef pair<int,int> Point;
const int dx[]={0,-1,0,1,1,-1,1,-1},dy[]={-1,0,1,0,-1,-1,1,1};
const int dx1[]={0,-1,0,1},dy1[]={-1,0,1,0};
Point p[205];
int T,m,n,K;
int main(){
    scanf("%d",&T);
    for(int zu=1;zu<=T;++zu){
        map<Point,int>vis;
        set<Point>za;
        vector<ll>vs;
        printf("Case #%d:\n",zu);
        scanf("%d%d%d",&n,&m,&K);
        for(int i=1;i<=K;++i){
            scanf("%d%d",&p[i].first,&p[i].second);
            za.insert(p[i]);
        }
        int bj=0;
        for(int i=1;i<=K;++i){
            int x=p[i].first,y=p[i].second;
            for(int j=0;j<8;++j){
                int tx=x+dx[j],ty=y+dy[j];
                if(tx>=1 && tx<=n && ty>=1 && ty<=m){
                    if(za.find(Point(tx,ty))==za.end()){
                        if(!vis[Point(tx,ty)]){
                            ++bj;
                            queue<Point>q;
                            q.push(Point(tx,ty));
                            vis[Point(tx,ty)]=bj;
                            int cnt=1;
                            bool flag=1;
                            while(!q.empty()){
                                Point U=q.front();
                                q.pop();
                                for(int k=0;k<4;++k){
                                    int ttx=U.first+dx1[k],tty=U.second+dy1[k];
                                    if(ttx>=1 && ttx<=n && tty>=1 && tty<=m && za.find(Point(ttx,tty))==za.end()){
                                        int tmp=vis[Point(ttx,tty)];
                                        if(tmp>0 && tmp<bj){
                                            flag=0;
                                            break;
                                        }
                                        else if(tmp==0){
                                            q.push(Point(ttx,tty));
                                            ++cnt;
                                            vis[Point(ttx,tty)]=bj;
                                            if(cnt>40000){
                                                flag=0;
                                                goto OUT;
                                            }
                                        }
                                    }
                                }
                            }
                            OUT:
                            if(flag){
                                vs.push_back((ll)cnt);
                            }
                        }
                    }
                }
            }
        }
        ll sum=0;
        for(vector<ll>::iterator it=vs.begin();it!=vs.end();++it){
            sum+=(*it);
        }
        if((ll)n*(ll)m>sum+(ll)K){
            vs.push_back((ll)n*(ll)m-sum-(ll)K);
        }
        sort(vs.begin(),vs.end());
        int sz=vs.size();
        printf("%d\n",sz);
        for(int i=0;i<sz;++i){
            printf("%lld",vs[i]);
            if(i==sz-1){
                puts("");
            }
            else{
                putchar(' ');
            }
        }
    }
    return 0;
}
    原文作者:AutSky_JadeK
    原文地址: https://www.cnblogs.com/autsky-jadek/p/7885600.html
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞