离散化+dfs+连通块计数 HDU 5925 Coconuts

Describe

多组测试t

输入一个map大小X * Y,map中有n个障碍点,输入n个障碍点的坐标,问map有几个连通块

Solution

如果地图不大完全可以dfs/bfs去做,但是X,Y【1,1e9】就需要进行离散化

可见障碍点n很少,最多200个

输入完障碍点后,分x,y轴进行离散处理

排序后去除一维坐标重合的点,然后进行离散处理,障碍点间(包括障碍点和边界之间)距离大于1才进行离散,然后还要分配每个障碍点坐标并进行记录

x,y轴离散完毕后,进行新地图的映射,主要是障碍点的映射

然后bfs四处搜索就可以了

一共需要存储:
整型:

X,Y 地图大小

n 障碍点大小

ans 连通块个数

数组:

Pair P 初始障碍点坐标

sorted_X,sorted_Y 包含边界点的 排号序的一维映射

cpl_X,cpl_y 映射好的一维坐标

new_mp 映射好的新地图

ret 每个连通块的大小

Code

#include 

using namespace std;
typedef long long ll;
const int maxn = 210 * 2;
int X,Y,n;
pair p[maxn];
int x[maxn],y[maxn];
int ls_x[maxn];
int ls_y[maxn];
int new_mp[maxn][maxn];
int x_num,y_num;
ll ans[maxn*maxn];
int ret;
void dfs(int a,int b){
    ans[ret] += (ll)ls_x[a] * ls_y[b];
    new_mp[a][b] = 1;
    if(a > 0 && !new_mp[a-1][b])dfs(a-1,b);
    if(a < x_num - 1 && !new_mp[a+1][b])dfs(a+1,b);
    if(b > 0 && !new_mp[a][b-1])dfs(a,b-1);
    if(b < y_num-1 && !new_mp[a][b+1])dfs(a,b+1);
}
int main()
{
    int t;
    scanf("%d",&t);
    for(int cas = 1;cas <= t;++cas){
        scanf("%d%d",&X,&Y);
        scanf("%d",&n);
        //把范围扩大1,防止边界有障碍物
        x[0] = y[0] = 0;
        x[1] = X + 1;
        y[1] = Y + 1;

        for(int i = 1;i <= n;++i){
            scanf("%d%d",&p[i].first,&p[i].second);
            x[i+1] = p[i].first;
            y[i+1] = p[i].second;
        }
        int cnt;
        sort(x,x+n+2);
        cnt = unique(x,x+n+2) - x;
        x_num = 0;
        for(int i = 1;i < cnt;++i){
            if(x[i] - x[i-1] > 1)ls_x[x_num++] = x[i] - x[i-1] - 1;
            if(i != cnt-1)ls_x[x_num++] = 1;
            for(int j = 1;j <= n;++j){
                if(p[j].first == x[i]){
                    p[j].first = x_num-1;
                    //break;
                }
            }
        }
        sort(y,y+n+2);
        cnt = unique(y,y+n+2) - y;
        y_num = 0;
        for(int i = 1;i < cnt;++i){
            if(y[i] - y[i-1] > 1)ls_y[y_num++] = y[i] - y[i-1] - 1;
            if(i != cnt-1)ls_y[y_num++] = 1;
            for(int j = 1;j <= n;++j){
                if(p[j].second == y[i]){
                    p[j].second = y_num-1;
                    //break;
                }
            }
        }

        for(int i = 0;i < x_num;++i){
            for(int j = 0;j < y_num;++j){
                new_mp[i][j] = 0;
            }
        }

        for(int i = 1;i <= n;++i)
            new_mp[p[i].first][p[i].second] = 1;

        ret = 0;
        memset(ans,0,sizeof(ans));

        for(int i = 0;i < x_num;++i){
            for(int j = 0;j < y_num;++j){
                if(!new_mp[i][j]){
                    ret++;
                    dfs(i,j);
                }
            }
        }
        sort(ans+1,ans+1+ret);
        printf("Case #%d:\n%d\n",cas,ret);
        for(int i = 1;i <= ret;++i){
            if(i == 1)printf("%I64d",ans[i]);
            else printf(" %I64d",ans[i]);
        }
        printf("\n");
    }
    return 0;
}

 

你可能感兴趣的:(算法思想)