1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119
|
#include<bits/stdc++.h> #define re register typedef long long ll; template<class T> inline void read(T &x) { x=0; char ch=getchar(),t=0; while(ch<'0'||ch>'9') t|=ch=='-',ch=getchar(); while(ch>='0'&&ch<='9') x=(x<<3)+(x<<1)+(ch^48),ch=getchar(); if(t) x=-x; } template<class T,class ...T1> inline void read(T &x,T1 &...x1){ read(x),read(x1...); } template<class T> inline void write(T x) { if(x<0) putchar('-'),x=-x; if(x>9) write(x/10); putchar(x%10+'0'); } template<> inline void write(bool x){ std::cout<<x; } template<> inline void write(char c){ putchar(c); } template<> inline void write(char *s){ while(*s!='\0') putchar(*s++); } template<> inline void write(const char *s){ while(*s!='\0') putchar(*s++); } template<class T,class ...T1> inline void write(T x,T1 ...x1){ write(x),write(x1...); } template<class T> inline bool checkMax(T &x,T y){ return x<y?x=y,1:0; } template<class T> inline bool checkMin(T &x,T y){ return x>y?x=y,1:0; } using Pir=std::pair<int,int>; #define fir first #define sec second const int MAXN=3e2+10,MAXM=9e4+10; const int INF=0x3f3f3f3f; const int dx[]={0,1,-1,0,0}; const int dy[]={0,0,0,1,-1}; int N,M,P; std::vector<Pir>vec[MAXM]; int a[MAXN][MAXN],Dist[MAXN][MAXN][2],fr,to; inline int getDist(Pir a,Pir b){ return std::abs(a.fir-b.fir)+std::abs(a.sec-b.sec); } inline bool cmp(Pir a,Pir b){ return Dist[a.fir][a.sec][fr]<Dist[b.fir][b.sec][fr]; } inline void calcCount(int s) { fr=(s-1)&1,to=s&1; for(auto v:vec[s]) Dist[v.fir][v.sec][to]=INF; for(auto x:vec[s-1]) for(auto v:vec[s]) checkMin(Dist[v.fir][v.sec][to],Dist[x.fir][x.sec][fr]+getDist(x,v)); } bool Vis[MAXN][MAXN]; inline int dis(Pir a){ return Dist[a.fir][a.sec][to]; } inline void calcBfs(int s) { fr=(s-1)&1,to=s&1; for(int i=1;i<=N;++i) for(int j=1;j<=M;++j) Dist[i][j][to]=INF,Vis[i][j]=0; std::sort(vec[s-1].begin(),vec[s-1].end(),cmp); for(auto x:vec[s-1]) Dist[x.fir][x.sec][to]=Dist[x.fir][x.sec][fr]; std::deque<Pir>Q; Q.push_front(vec[s-1][0]),Vis[vec[s-1][0].fir][vec[s-1][0].sec]=1; int pos=1,siz=vec[s-1].size()-1; while(!Q.empty()) { auto u=Q.front();Q.pop_front(); while(pos<=siz&&Dist[u.fir][u.sec][to]==dis(vec[s-1][pos])) { if(!Vis[vec[s-1][pos].fir][vec[s-1][pos].sec]) Q.push_front(vec[s-1][pos]),Vis[vec[s-1][pos].fir][vec[s-1][pos].sec]=1; ++pos; } for(int k=1;k<=4;++k) { int nx=u.fir+dx[k],ny=u.sec+dy[k]; if(nx<1||nx>N||ny<1||ny>M||Vis[nx][ny]) continue; Dist[nx][ny][to]=Dist[u.fir][u.sec][to]+1,Q.push_back({nx,ny}); Vis[nx][ny]=1; } } for(int i=1;i<=N;++i) for(int j=1;j<=M;++j) if(a[i][j]!=s) Dist[i][j][to]=INF; } inline void print(int id) { for(int i=1;i<=N;++i,puts("")) for(int j=1;j<=M;++j) write(Dist[i][j][id],' '); puts(""); } int main() { read(N,M,P); for(int i=1;i<=N;++i) for(int j=1;j<=M;++j) read(a[i][j]),vec[a[i][j]].push_back({i,j}); vec[0].push_back({1,1}); Dist[1][1][0]=0; for(int i=1;i<=P;++i) { int a=vec[i-1].size(),b=vec[i].size(); if((ll)a*b<=4*N*M) calcCount(i); else calcBfs(i); } write(Dist[vec[P][0].fir][vec[P][0].sec][P&1]); return 0; }
|