Canyon Crossing(二分+bfs)

Canyon Crossing 计蒜客 - 43467

64000K
The Bridge And Passageway Creators are responsible for making new paths through the local mountains. They have approved your plan to build a new route through your favorite canyon.You feverishly start working on this beautiful new path, when you realize you failed to take into account the flow of a nearby river: the canyon is flooded! Apparently this happens once every blue moon, making some parts of the path inaccessible. Because of this, you want to build a path such that the lowest point on the path is as high as possible. You quickly return to the village and use all of your money to buy rope bridges. You plan to use these to circumvent the lowest parts of the canyon.

C1.jpg

Figure C.1: Canyon and two possible paths with minimal height 1 and 2 for sample input 1. The B indicate bridges.

Your map of the canyon consists of a rectangular grid of cells, each containing a number giving the height of the terrain at that cell. The path will go from the south side of the canyon(bottom on your map) to the north side (top of your map), moving through a connected sequence of cells. Two cells are considered connected if and only if they share an edge. Inparticular, two diagonally touching cells are not considered to be connected. This means that for any cell not on the edge of the map, there are 4 other cells connected to it. The left of figure C.1 contains the map for the first sample input.

The path through the canyon can start on any of the bottom cells of the grid, and end on any of the cells in the top tow, like the two paths on the right in C.1. The lowest height is given by the lowest height of any of the cells the paths goes through. Each bridge can be used to cross exactly one cell. This cell is then not taken into account when calculating the minimal height of the path.

Note that is allowed to chain multiple bridges to use them to cross multiple cells,Given the map of the canyon and the number of bridges available, find the lowest height of an optimal path.

C2.jpg

INPUT:

• A single line containing three integers: 1 ≤ R ≤ 1000 and 1 ≤ C ≤ 1000, the size of the

map, and 0 ≤ K ≤ R-1, the number of bridges you can build.

• This is followed by R lines each containing C integers. The j-th integer on the i-th line

corresponds to the height 0 ≤ Hi,j ≤ 10^9 of the canyon at point (i, j). The fifirst line

corresponds to the northern edge of the canyon, the last line to the southern edge.

OUTPUT:

Output a single integer, the lowest height of the optimal path.

样例输入 复制
5 3 1
1 1 3
3 3 3
0 0 0
2 2 1
1 2 1
样例输出 复制
2

题意:n行m列,从最后一行走到第一行,每个点的值代表这个点的高度,你要计算这条路上最低高度的最大值,有一个K,在这条路上可以无视至多k个点的权值

  • 二分答案,队列que[i]储存已经用过i次无视条件的点,bfs判断
#include<bits/stdc++.h>
using namespace std;
const int maxn = 1200;
const int mod = 1e9+7;
int m,n,k;
bool flag[maxn][maxn];
int Map[maxn][maxn];
int a[] = {0,1, 0,-1, 1,0,-1,0};

bool judge(int mid)
{
    memset(flag,0,sizeof(flag));
    queue<pair<int,int> >que[k+2];
    for(int i = 1; i<=m; i++)
    {
        flag[n][i] = 1;
        que[Map[n][i]<mid?1:0].push(make_pair(n,i));
    }

    for(int i = 0; i<=k; i++)
    {
        while(!que[i].empty())
        {
            pair<int,int>p = que[i].front();
            if(p.first==1)
            {
                return 1;

            }
            que[i].pop();
            for(int j = 0; j<=6; j+=2)
            {
                int x = p.first+a[j];
                int y = p.second+a[j+1];
                if(x<1||y<1||x>=n||y>m)
                    continue;
                if(!flag[x][y])
                {
                    flag[x][y]= 1;
                    que[Map[x][y]<mid?i+1:i].push(make_pair(x,y));
                }
            }

        }
    }
    //printf("asdfasdf\n");
    return 0;
}


int main()
{
    int i,j,ans;
    cin>>n>>m>>k;
    int maxn = -1;
    for(i = 1; i<=n; i++)
    {
        for(j = 1; j<=m; j++)
        {
            cin>>Map[i][j];
            maxn = max(maxn,Map[i][j]);
        }
    }

    int l = 0;
    int r = maxn;
    ans = r;
    while(l<=r)
    {
        int mid = (l+r)>>1;
        if(judge(mid))
        {
            ans = mid;
            l = mid+1;
        }
        else
            r = mid-1;
    }
    cout<<ans<<endl;

    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值