zoukankan      html  css  js  c++  java
  • CF677D Vanya and Treasure(最短路)

    本题容易看出分层的样子

    对于i-1来更新i的答案。我们对于更新有两种选择,一种是直接枚举点对更新,一种是用spfa进行o(N*M)更新

    我们发现对于两种情况的最坏复杂度情况不同,因此可以进行讨论选择使用哪一种更新、

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    typedef pair<int,int> pll;
    const int N=2e6+10;
    const int inf=0x3f3f3f3f;
    int n,m,p;
    int a[500][500];
    vector<pll> g[N];
    int dis[500][500];
    int dis2[500][500];
    int st[500][500];
    int dx[]={-1,0,1,0};
    int dy[]={0,1,0,-1};
    struct node{
        int cnt;
        int a,b;
    };
    int cal(pll a,pll b){
        return abs(a.first-b.first)+abs(a.second-b.second);
    }
    void make(int x){
        int i,j;
        for(i=0;i<g[x].size();i++){
            auto t=g[x][i];
            for(j=0;j<g[x+1].size();j++){
                auto tmp=g[x+1][j];
                int d=cal(t,tmp);
                if(dis[tmp.first][tmp.second]>dis[t.first][t.second]+d){
                    dis[tmp.first][tmp.second]=dis[t.first][t.second]+d;
                }
            }
        }
    }
    void spfa(int x){
        memset(dis2,0x3f,sizeof dis2);
        memset(st,0,sizeof st);
        int i,j;
        queue<node> q;
        for(i=0;i<g[x].size();i++){
            auto t=g[x][i];
            q.push({dis[t.first][t.second],t.first,t.second});
            st[t.first][t.second]=1;
            dis2[t.first][t.second]=dis[t.first][t.second];
        }
        while(q.size()){
            auto t=q.front();
            q.pop();
            st[t.a][t.b]=0;
            int a=t.a,b=t.b;
            for(i=0;i<4;i++){
                int x1=a+dx[i];
                int y=b+dy[i];
                if(x1&&x1<=n&&y&&y<=m){
                    if(dis2[x1][y]>dis2[a][b]+1){
                        dis2[x1][y]=dis2[a][b]+1;
                        if(!st[x1][y]){
                            q.push({dis2[x1][y],x1,y});
                            st[x1][y]=1;
                        }
    
                    }
                }
            }
        }
        for(i=0;i<g[x+1].size();i++){
            auto t=g[x+1][i];
            dis[t.first][t.second]=dis2[t.first][t.second];
        }
    }
    void solve(){
        int i,j;
        for(i=0;i<(int)g[1].size();i++){
            int a=g[1][i].first,b=g[1][i].second;
            dis[a][b]=cal(g[1][i],{1,1});
        }
        for(i=1;i<p;i++){
            if((int)g[i].size()*(int)g[i+1].size()<n*m){
                make(i);
            }
            else{
                spfa(i);
            }
        }
    }
    int main(){
        ios::sync_with_stdio(false);
        cin>>n>>m>>p;
        int i,j;
        for(i=1;i<=n;i++){
            for(j=1;j<=m;j++){
                cin>>a[i][j];
                g[a[i][j]].push_back({i,j});
            }
        }
        memset(dis,0x3f,sizeof dis);
        solve();
        auto t=g[p][0];
        ll ans=dis[t.first][t.second];
        cout<<ans<<endl;
    }
    View Code
  • 相关阅读:
    黑客无处不在
    微博对我的影响
    WPF Chart DynamicDataDisplay的横坐标显示日期的解决方案
    java虚拟机中的字节码
    python解释器的使用
    Python学习环境设置
    变量的概念
    创建虚拟环境和常用包
    第三章笔记
    第一章笔记
  • 原文地址:https://www.cnblogs.com/ctyakwf/p/13799086.html
Copyright © 2011-2022 走看看