uva 12130 - Summits(BFS)

737 篇文章 0 订阅
223 篇文章 1 订阅

题目链接:uva 12130 - Summits

题目大意:给定一个NM的图,每个位置有一个值。给定D,表示有节点值为G的位置作为起点的话,将不能移动到值小于等于GD的节点。现在要求找到整个图中所有的峰值点,峰值点的定义是不能移动到比自己节点值大的位置。

解题思路:将每个位置按照权值排序,逐个作为起点进行移动,v[x][y]数组值可以到达x,y的节点的值的最大值,如果起始点可以移动到v[x][y]大于本身的点,则说明该起点不是峰值点。

#include <cstdio>
#include <cstring>
#include <queue>
#include <algorithm>

using namespace std;
const int maxn = 505;
const int dir[4][2] = {{1, 0}, {-1, 0}, {0, 1}, {0, -1}};

struct point {
    int x, y, val;
    point (int x = 0, int y = 0, int val = 0) {
        this->x = x;
        this->y = y;
        this->val = val;
    }
    bool operator < (const point& u) const {
        return val > u.val;
    }
};

int N, M, D, g[maxn][maxn], v[maxn][maxn];
vector<point> vec;

void init () {
    vec.clear();

    memset(v, 0, sizeof(v));
    scanf("%d%d%d", &N, &M, &D);

    for (int i = 1; i <= N; i++) {
        for (int j = 1; j <= M; j++) {
            scanf("%d", &g[i][j]);
            vec.push_back(point(i, j, g[i][j]));
        }
    }
    sort(vec.begin(), vec.end());
}

int bfs (int x, int y, int h) {
    int ret = 1;
    bool flag = true;
    queue<point> que;
    que.push(point(x, y));

    while (!que.empty()) {
        point u = que.front();
        que.pop();

        for (int i = 0; i < 4; i++) {
            int p = u.x + dir[i][0];
            int q = u.y + dir[i][1];

            if (p <= 0 || p > N || q <= 0 || q > M)
                continue;

            if (h - g[p][q] >= D)
                continue;

            if (v[p][q] > h) {
                flag = false;
                continue;
            }

            if (v[p][q] == h)
                continue;

            if (g[p][q] == h)
                ret++;
            v[p][q] = h;
            que.push(point(p, q));
        }
    }
    //printf("%d %d %d %d\n", x, y, g[x][y], ret);

    if (flag == false)
        return 0;
    return ret;
}

int solve () {
    int ret = 0;
    for (int i = 0; i < vec.size(); i++) {
        int x = vec[i].x, y = vec[i].y;
        if (v[x][y])
            continue;
        v[x][y] = g[x][y];
        ret += bfs(x, y, g[x][y]);
    }
    return ret;
}

int main () {
    int cas;
    scanf("%d", &cas);

    while (cas--) {
        init();
        printf("%d\n", solve());
    }
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值