zoukankan      html  css  js  c++  java
  • codeforces 821 D. Okabe and City(最短路)

    题目链接:http://codeforces.com/contest/821/problem/D

    题意:n*m地图,有k个位置是点亮的,有4个移动方向,每次可以移动到相邻的点亮位置,每次站在初始被点亮某个位置,暂时使某行或该某列全部点亮,花费为1,下一次使用时,上一次暂时点亮被熄灭

    题解:显然只要知道如果两点相邻直接相连然后就是极限情况,什么情况之下是两点是连不到一起的。如果x轴与y轴的相差大于2是连不到一起的。

    具体画一下图就知道了。然后就跑一遍dij+优先队列就行了或者spfa也行。

    #include <iostream>
    #include <cstring>
    #include <cstdio>
    #include <queue>
    #include <cmath>
    #define inf 0X3f3f3f3f
    using namespace std;
    const int M = 1e4 + 10;
    typedef long long ll;
    ll dis[M];
    bool vis[M];
    int n , m , k , flag;
    struct TnT {
        int x , y;
    }T[M];
    struct qnode {
        int v;
        ll c;
        qnode(int v , ll c):v(v) , c(c) {}
        bool operator <(const qnode &r) const{
            return c > r.c;
        }
    };
    void dij() {
        priority_queue<qnode>q;
        memset(vis , false , sizeof(vis));
        q.push(qnode(1 , 0));
        dis[1] = 0;
        while(!q.empty()) {
            int u = q.top().v;
            q.pop();
            if(vis[u]) continue;
            vis[u] = true;
            for(int i = 1 ; i <= k ; i++) {
                int v = i;
                int dx = abs(T[u].x - T[v].x) , dy = abs(T[u].y - T[v].y);
                if(dx + dy == 1) {
                    if(!flag && T[v].x == n && T[v].y == m) {
                        if(dis[v] > dis[u] + 1 && !vis[v]) {
                            dis[v] = dis[u] + 1;
                            q.push(qnode(v , dis[v]));
                        }
                    }
                    else {
                        if(dis[v] > dis[u] && !vis[v]) {
                            dis[v] = dis[u];
                            q.push(qnode(v , dis[v]));
                        }
                    }
                }
                else {
                    if(dx <= 2 || dy <= 2) {
                        if(!flag) {
                            if(T[v].x == n && T[v].y == m) {
                                if(dx <= 1 || dy <= 1) {
                                    if(dis[v] > dis[u] + 1 && !vis[v]) {
                                        dis[v] = dis[u] + 1;
                                        q.push(qnode(v , dis[v]));
                                    }
                                }
                            }
                            else {
                                if(dis[v] > dis[u] + 1 && !vis[v]) {
                                    dis[v] = dis[u] + 1;
                                    q.push(qnode(v , dis[v]));
                                }
                            }
                        }
                        else {
                            if(dis[v] > dis[u] + 1 && !vis[v]) {
                                dis[v] = dis[u] + 1;
                                q.push(qnode(v , dis[v]));
                            }
                        }
                    }
                }
            }
        }
    }
    int main() {
        flag = 0;
        scanf("%d%d%d" , &n , &m , &k);
        for(int i = 1 ; i <= k ; i++) {
            scanf("%d%d" , &T[i].x , &T[i].y);
            if(T[i].x == n && T[i].y == m) flag = 1;
            dis[i] = inf;
        }
        if(!flag) {
            T[k + 1].x = n , T[k + 1].y = m;
            k++;
            dis[k] = inf;
        }
        dij();
        if(dis[k] >= inf) printf("%d
    " , -1);
        else printf("%lld
    " , dis[k]);
        return 0;
    }
    
  • 相关阅读:
    [Tutorial] Using the RasPi as a WiFi hostspot
    Turn Your Raspberry Pi Into a WiFi Hotspot with Edimax Nano USB EW-7811Un (RTL8188CUS chipset)
    RPI-Wireless-Hotspot
    将树莓派Raspberry Pi设置为无线路由器(WiFi热点AP,RTL8188CUS芯片)
    java的动态代理机制详解
    ant -verbose -debug ...
    各个版本的spring jar包
    挑战树莓派:谁才是Geek最爱的开发板?
    RPi Debian Auto Login
    IP查找工具——angry IP Scanner
  • 原文地址:https://www.cnblogs.com/TnT2333333/p/7093674.html
Copyright © 2011-2022 走看看