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;
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章