luogu P4009 汽车加油行驶问题

网络流(×),多层图BFS(√)

typedef long long LL;
typedef pair<LL, LL> PLL;
typedef pair<int, int> PINT;

const int maxm = 115;
const LL INF = 0x3f3f3f3f3f3f3f3f;
const int dx[] = {1, -1, 0, 0};
const int dy[] = {0, 0, 1, -1};

LL d[maxm][maxm][13];
int G[maxm][maxm];
bool inq[maxm][maxm][13];

struct Node {
    int x, y, k;
};

void run_case() {
    memset(d, 63, sizeof(d));
    int N, K, A, B, C;
    cin >> N >> K >> A >> B >> C;
    for(int i = 1; i <= N; ++i)
        for(int j = 1; j <= N; ++j)
            cin >> G[i][j];
    queue<Node> q;
    q.push(Node{1, 1, K}); inq[1][1][K] = true;
    d[1][1][K] = 0;
    while(!q.empty()) {
        auto now = q.front(); q.pop();
        inq[now.x][now.y][now.k] = false;
        if(G[now.x][now.y] && now.k != K) {
            if(d[now.x][now.y][K] > d[now.x][now.y][now.k]+A) {
                d[now.x][now.y][K] = d[now.x][now.y][now.k]+A;
                if(!inq[now.x][now.y][K]) {
                    inq[now.x][now.y][K] = true;
                    q.push(Node{now.x, now.y, K});
                }
            }
            continue;
        } else if(!G[now.x][now.y]){
            if(d[now.x][now.y][K] > d[now.x][now.y][now.k]+A+C) {
                d[now.x][now.y][K] = d[now.x][now.y][now.k]+A+C;
                if(!inq[now.x][now.y][K]) {
                    inq[now.x][now.y][K] = true;
                    q.push(Node{now.x, now.y, K});
                }
            }
        }
        if(now.k > 0) {
            for(int i = 0; i < 4; ++i) {
                int nx = now.x + dx[i], ny = now.y + dy[i];
                if(nx < 1 || nx > N || ny < 1 || ny > N) continue;
                int cost = 0;
                if(nx < now.x || ny < now.y) cost = B;
                if(d[nx][ny][now.k-1] > d[now.x][now.y][now.k] + cost) {
                    d[nx][ny][now.k-1] = d[now.x][now.y][now.k] + cost;
                    if(!inq[nx][ny][now.k-1]) {
                        inq[nx][ny][now.k-1] = true;
                        q.push(Node{nx, ny, now.k-1});
                    }
                }
            }
        }
        
    }
    LL ans = INF+5;
    for(int i = 0; i <= K; ++i)
        ans = min(ans, d[N][N][i]);
    cout << ans;
}

int main() {
    ios::sync_with_stdio(false), cin.tie(0);
    run_case();
    //cout.flush();
    return 0;
}
View Code

 

posted @ 2020-02-08 14:13  GRedComeT  阅读(184)  评论(0编辑  收藏  举报