zoukankan      html  css  js  c++  java
  • BZOJ 1001 [BeiJing2006]狼抓兔子

    [BeiJing2006]狼抓兔子

    思路:

    将边转换成点,每个小三角形两两连边,跑从左下到右上的最短路。

    代码:

    #pragma GCC optimize(2)
    #pragma GCC optimize(3)
    #pragma GCC optimize(4)
    #include<bits/stdc++.h>
    using namespace std;
    #define y1 y11
    #define fi first
    #define se second
    #define pi acos(-1.0)
    #define LL long long
    #define ls rt<<1, l, m
    #define rs rt<<1|1, m+1, r
    //#define mp make_pair
    #define pb push_back
    #define ULL unsigned LL
    #define pll pair<LL, LL>
    #define pli pair<LL, int>
    #define pii pair<int, int>
    #define piii pair<pii, int>
    #define pdi pair<double, int>
    #define pdd pair<double, double>
    #define mem(a, b) memset(a, b, sizeof(a))
    #define debug(x) cerr << #x << " = " << x << "
    ";
    #define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
    //head
    
    const int N = 1e3 + 10;
    int a, n, m, cnt = 0;
    int ida[N][N], idb[N][N], idc[N][N], w[N*N*3];
    LL d[N*N*3];
    vector<int> g[N*N*3];
    priority_queue<pli, vector<pli>, greater<pli> > q;
    int main() {
        scanf("%d %d", &n, &m);
        for (int i = 1; i <= n; ++i) {
            for (int j = 1; j <= m-1; ++j) scanf("%d", &a), ida[i][j] = ++cnt, w[cnt] = a;
        }
        for (int i = 1; i <= n-1; ++i) {
            for (int j = 1; j <= m; ++j) scanf("%d", &a), idb[i][j] = ++cnt, w[cnt] = a;
        }
        for (int i = 1; i <= n-1; ++i) {
            for (int j = 1; j <= m-1; ++j) scanf("%d", &a), idc[i][j] = ++cnt, w[cnt] = a;
        }
        for (int i = 1; i <= n; ++i) {
            for (int j = 1; j <= m-1; ++j) {
                if(i <= n-1) g[ida[i][j]].pb(idb[i][j+1]);
                if(i <= n-1) g[ida[i][j]].pb(idc[i][j]);
                if(i >= 2)   g[ida[i][j]].pb(idb[i-1][j]);
                if(i >= 2)   g[ida[i][j]].pb(idc[i-1][j]);
            }
        }
        for (int i = 1; i <= n-1; ++i) {
            for (int j = 1; j <= m; ++j) {
                if(j <= m-1) g[idb[i][j]].pb(ida[i+1][j]);
                if(j <= m-1) g[idb[i][j]].pb(idc[i][j]);
                if(j >= 1)   g[idb[i][j]].pb(ida[i][j-1]);
                if(j >= 1)   g[idb[i][j]].pb(idc[i][j-1]);
            }
        }
        for (int i = 1; i <= n-1; ++i) {
            for (int j = 1; j <= m-1; ++j) {
                g[idc[i][j]].pb(ida[i][j]);
                g[idc[i][j]].pb(idb[i][j]);
                g[idc[i][j]].pb(ida[i+1][j]);
                g[idc[i][j]].pb(idb[i][j+1]);
            }
        }
        mem(d, 0x3f);
        for (int j = 1; j <= m-1; ++j) {
            d[ida[n][j]] = w[ida[n][j]];
            q.push({w[ida[n][j]], ida[n][j]});
        }
        for (int i = 1; i <= n-1; ++i) {
            d[idb[i][1]] = w[idb[i][1]];
            q.push({w[idb[i][1]], idb[i][1]});
        }
        while(!q.empty()) {
            pli p = q.top();
            q.pop();
            int u = p.se;
            if(d[u] < p.fi) continue;
            for (int i = 0; i < g[u].size(); ++i) {
                int v = g[u][i];
                if(d[v] > d[u] + w[v]) {
                    d[v] = d[u] + w[v];
                    q.push({d[v], v});
                }
            }
        }
        LL ans = 1LL<<60;
        for (int j = 1; j <= m-1; ++j) {
            ans = min(d[ida[1][j]], ans);
        }
        for (int i = 1; i <= n-1; ++i) {
            ans = min(d[idb[i][m]], ans);
        }
        printf("%lld
    ", ans);
        return 0;
    }
  • 相关阅读:
    Java学习开篇
    《我的姐姐》
    世上本无事,庸人自扰之
    这48小时
    补觉
    淡定
    es java api 设置index mapping 报错 mapping source must be pairs of fieldnames and properties definition.
    java mongodb groupby分组查询
    linux 常用命令
    mongodb too many users are authenticated
  • 原文地址:https://www.cnblogs.com/widsom/p/10790233.html
Copyright © 2011-2022 走看看