#420 Div2 D

#420 Div2 D

题意

给出一个方格矩阵,其中存在亮着的方格,只能在亮着的方格上行走,可以在初始亮的方格上花费一枚硬币临时点亮任意一行或一列,地图上同一时间只能存在一个这样的行或列,问走到终点最少花费的硬币。

分析

对可以行走的格子建图,如果格子相邻,花费为0,如果行差或列差小于等于2,则花费为1,否则就不能到达了。跑一遍 SPFA 即可。

code

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int MAXN = 10005;
const int INF = 0x3f3f3f3f;
int x[MAXN], y[MAXN];
int n, m, k;
queue<int> q;
int vis[MAXN];
int dis[MAXN];
int SPFA() {
    while(!q.empty()) q.pop();
    memset(vis, 0, sizeof vis);
    memset(dis, 0x3f, sizeof dis);
    dis[1] = 0;
    vis[1] = 1;
    q.push(1);
    while(!q.empty()) {
        int u = q.front(); q.pop();
        vis[u] = 0;
        for(int i = 1; i <= k; i++) {
            if(i == u) continue;
            int dx = abs(x[u] - x[i]), dy = abs(y[u] - y[i]);
            int add = INF;
            if(dx <= 2 || dy <= 2) add = 1;
            if(dx + dy == 1) add = 0;
            if(dis[i] > dis[u] + add) {
                dis[i] = dis[u] + add;
                if(!vis[i]) {
                    q.push(i);
                    vis[i] = 1;
                }
            }
        }
    }
    if(dis[k] >= INF) dis[k] = -1;
    return dis[k];
}
int main() {
    cin >> n >> m >> k;
    int f = 0;
    for(int i = 1; i <= k; i++) {
        cin >> x[i] >> y[i];
        if(x[i] == n && y[i] == m) {
            f = 1;
        }
    }
    if(!f) {
        x[++k] = n + 1;
        y[k] = m + 1;
    }
    cout << SPFA() << endl;
    return 0;
}
posted @ 2017-06-29 18:00  ftae  阅读(201)  评论(0编辑  收藏  举报