Codeforces Round #542(Div. 2) C.Connect

链接:https://codeforces.com/contest/1130/problem/C

题意:

给一个n*n的图,0表示地面,1表示水,给出起点和终点,

现要从起点到达终点,有一次在两个坐标间创立隧道的机会,消耗为(x1 - x2)^2 + (y1 - y1)^2。

求出最小的消耗,如果直接能走到,则消耗为0。

思路:

bfs求出起点和终点分别能到达的点,枚举每一种情况,取最小值即可。

代码:

#include <bits/stdc++.h>

using namespace std;

typedef long long LL;

int Next[4][2] = {{-1, 0}, {0, 1}, {1, 0}, {0, -1}};
const int MAXN = 50 + 5;
char Map[MAXN][MAXN];
int vis[MAXN][MAXN];
int n, r1, r2, c1, c2;

int Bfs()
{
    queue<pair<int, int>> que;
    vector<pair<int, int>> start;
    vector<pair<int, int>> ends;
    que.push(make_pair(r1, c1));
    vis[r1][c1] = 1;
    while (!que.empty())
    {
        int x = que.front().first;
        int y = que.front().second;
        start.push_back(make_pair(x, y));
        if (x == r2 && y == c2)
            return 0;
        for (int i = 0;i < 4;i++)
        {
            int nx = x + Next[i][0];
            int ny = y + Next[i][1];
            if (nx < 1 || nx > n || ny < 1 || ny > n)
                continue;
            if (vis[nx][ny] || Map[nx][ny] == '1')
                continue;
            vis[nx][ny] = 1;
            que.push(make_pair(nx, ny));
        }
        que.pop();
    }
    que.push(make_pair(r2, c2));
    vis[r2][c2] = 1;
    while (!que.empty())
    {
        int x = que.front().first;
        int y = que.front().second;
        ends.push_back(make_pair(x, y));
        for (int i = 0;i < 4;i++)
        {
            int nx = x + Next[i][0];
            int ny = y + Next[i][1];
            if (nx < 1 || nx > n || ny < 1 || ny > n)
                continue;
            if (vis[nx][ny] || Map[nx][ny] == '1')
                continue;
            vis[nx][ny] = 1;
            que.push(make_pair(nx, ny));
        }
        que.pop();
    }
    int res = 9999;
    /*
    for (int i = 0;i < start.size();i++)
        cout << start[i].first << ' ' << start[i].second << endl;
    cout << endl;
    for (int i = 0;i < ends.size();i++)
        cout << ends[i].first << ' ' << ends[i].second << endl;
    cout << endl;
     */
    for (int i = 0;i < start.size();i++)
    {
        for (int j = 0;j < ends.size();j++)
        {
            int cx = start[i].first - ends[j].first;
            int cy = start[i].second - ends[j].second;
            int cost = cx * cx + cy * cy;
            res = min(res, cost);
        }
    }
    return res;
}

int main()
{
    cin >> n;
    cin >> r1 >> c1 >> r2 >> c2;
    for (int i = 1;i <= n;i++)
    {
        for (int j = 1; j <= n; j++)
            cin >> Map[i][j];
    }
    cout << Bfs() << endl;

    return 0;
}

  

posted @ 2019-02-27 23:30  YDDDD  阅读(186)  评论(0编辑  收藏  举报