• USACO17FEB Why Did the Cow Cross the Road I G


    题目传送门

    难得不卡(SPFA)


    因为可爱的贝茜会走三步停一步,所以可以将这三步并为一步来考虑,花费的时间为t * 3 + cost[x][y]
    需要注意的是,贝茜可以走一步再走回来,所以她周围的点也要考虑到,这样一共是16个点
    另外,当贝茜到达终点时不一定正好走三步,所以要将和终点距离为(1,2)的点也连向终点

    建图结束后,跑一遍最短路就可以了

    #include <cstdio>
    #include <iostream>
    #include <cstring>
    #include <cmath>
    #include <algorithm>
    #include <queue>
    #define LL long long
    using namespace std;
    LL read() {
        LL k = 0, f = 1; char c = getchar();
        while(c < '0' || c > '9') {
            if(c == '-') f = -1;
            c = getchar();
        }
        while(c >= '0' && c <= '9')
          k = k * 10 + c - 48, c = getchar();
        return k * f;
    }
    struct zzz {
        int t, nex, len;
    }e[500010 << 1]; int head[100010], tot;
    void add(int x, int y, int z) {
        e[++tot].t = y;
        e[tot].len = z;
        e[tot].nex = head[x];
        head[x] = tot;
    }
    int mapp[110][110], n, t;
    inline int calc(int x, int y) {
        return (x-1) * n + y;
    }
    inline bool judge(int x, int y) {
        return x >= 1 && x <= n && y >= 1 && y <= n;
    }
    int fx[20] = {0, -2, -1, 1, 2, 2, 1, -1, -2, 0, 1, 0, -1, 0, 3, 0, -3};
    int fy[20] = {0, 1, 2, 2, 1, -1, -2, -2, -1, 1, 0, -1, 0, 3, 0, -3, 0};
    bool vis[100010]; int dis[100010];
    void SPFA(int s) {
        memset(dis, 127, sizeof(dis)); dis[s] = 0; vis[s] = 1;
        queue <int> q; q.push(s);
        while(!q.empty()) {
            int k = q.front(); q.pop(); vis[k] = 0;
            for(int i = head[k]; i; i = e[i].nex) {
                if(dis[e[i].t] > dis[k] + e[i].len) {
                    dis[e[i].t] = dis[k] + e[i].len;
                    if(!vis[e[i].t])
                        vis[e[i].t] = 1, q.push(e[i].t);
                }
            }
        }
    }
    int main() {
        n = read(), t = read();
        for(int i = 1; i <= n; ++i)
            for(int j = 1; j <= n; ++j) mapp[i][j] = read();
        for(int i = 1; i <= n; ++i)
            for(int j = 1; j <= n; ++j) {
                for(int k = 1; k <= 16; ++k) {
                    int xx = i + fx[k], yy = j + fy[k];
                    if(judge(xx, yy))
                        add(calc(i, j), calc(xx, yy), 3 * t + mapp[xx][yy]);
                }
            }
        add(calc(n-1, n-1), calc(n, n), t << 1);
        add(calc(n-2, n), calc(n, n), t << 1);
        add(calc(n, n-2), calc(n, n), t << 1);
        add(calc(n-1, n), calc(n, n), t);
        add(calc(n, n-1), calc(n, n), t);
    
        SPFA(calc(1, 1));
    
        printf("%d
    ", dis[calc(n, n)]);
        return 0;
    }
    
  • 相关阅读:
    Java第一次作业
    第十一次
    第十次
    第九次
    第八次作业
    第七次
    第六次
    第五次作业
    ##JAVA作业3
    ##Java作业2
  • 原文地址:https://www.cnblogs.com/morslin/p/11855302.html
Copyright © 2020-2023  润新知