题解:CF1065D Three Pieces
思路:
拆点跑最短路。
把 \(n^2\) 个点拆成 \(3n^2\) 个,对应马,象和车三种状态。
不同状态之间连一条 \(1\) 的边,相同的连 \(0\),连边按照三种棋的走法连即可。
对于要依次遍历 \(1,2,3,...,n^2\) 的限制,我们可以先以 \(1\) 的三种状态为起点跑最短路,接着以 \(2\) 的三种状态跑最短路,以此类推,到以 \(n^2-1\) 的三种状态为起点跑最短路,即可得出最终到 \(n^2\) 的最短路、
注意每次换起点跑最短路,除起点外上一次最短路的状态都要清除。
复杂度为 \(O(n^4\log n)\)。
const int N=11,inf=1e9;
int id[N][N],val[N*N],n;
vector<pair<int,int>>G[N*N*3];
int ds[N*N*3],dc[N*N*3];
bool vis[N*N*3];
int dx[8]={-2,-2,-1,-1,1,1,2,2},dy[8]={-1,1,-2,2,-2,2,-1,1};
void Dijistra(int St)
{
for(int i=1;i<=n*n;i++)
{
if(St==i) continue;
else for(int j=1;j<=3;j++)
ds[(i-1)*3+j]=dc[(i-1)*3+j]=inf;
}
memset(vis,0,sizeof(vis));
priority_queue<pair<int,int>>q;
q.push({-ds[(St-1)*3+1],(St-1)*3+1});
q.push({-ds[(St-1)*3+2],(St-1)*3+2});
q.push({-ds[(St-1)*3+3],(St-1)*3+3});
while(q.size())
{
auto [D,now]=q.top();q.pop();
if(vis[now]) continue;
vis[now]=1;
for(auto [to,val]:G[now])
{
if(ds[to]>ds[now]+1+val){
ds[to]=ds[now]+1+val,dc[to]=dc[now]+val;
q.push({-ds[to],to});
}
else if(ds[to]==ds[now]+1+val){
if(dc[to]>dc[now]+val){
dc[to]=dc[now]+val,q.push({-ds[to],to});
}
}
}
}
return;
}
int main()
{
fin>>n;
for(int i=1,x;i<=n;i++)
for(int j=1;j<=n;j++)
fin>>x,val[x]=(id[i][j]=(i-1)*n+j);
for(int i=1,x,y;i<=n;i++)
for(int j=1;j<=n;j++)
{
x=id[i][j];
for(int p=1;p<=3;p++)
for(int q=1;q<=3;q++)
{
if(q==1){
for(int k=0;k<8;k++)
{
int nx=i+dx[k],ny=j+dy[k];
if(nx<1||ny<1||nx>n||ny>n) continue;
y=id[nx][ny];
G[(x-1)*3+p].push_back({(y-1)*3+q,p!=q});
}
}
if(q==2){
for(int nx=i-1,ny=j-1;nx&&ny;nx--,ny--)
y=id[nx][ny],G[(x-1)*3+p].push_back({(y-1)*3+q,p!=q});
for(int nx=i-1,ny=j+1;nx&&ny<=n;nx--,ny++)
y=id[nx][ny],G[(x-1)*3+p].push_back({(y-1)*3+q,p!=q});
for(int nx=i+1,ny=j-1;nx<=n&&ny;nx++,ny--)
y=id[nx][ny],G[(x-1)*3+p].push_back({(y-1)*3+q,p!=q});
for(int nx=i+1,ny=j+1;nx<=n&&ny<=n;nx++,ny++)
y=id[nx][ny],G[(x-1)*3+p].push_back({(y-1)*3+q,p!=q});
}
if(q==3){
for(int nx=i,ny=j+1;ny<=n;ny++)
y=id[nx][ny],G[(x-1)*3+p].push_back({(y-1)*3+q,p!=q});
for(int nx=i,ny=j-1;ny;ny--)
y=id[nx][ny],G[(x-1)*3+p].push_back({(y-1)*3+q,p!=q});
for(int nx=i-1,ny=j;nx;nx--)
y=id[nx][ny],G[(x-1)*3+p].push_back({(y-1)*3+q,p!=q});
for(int nx=i+1,ny=j;nx<=n;nx++)
y=id[nx][ny],G[(x-1)*3+p].push_back({(y-1)*3+q,p!=q});
}
}
}
for(int i=1;i<n*n;i++) Dijistra(val[i]);
pair<int,int>x={ds[(val[n*n]-1)*3+1],dc[(val[n*n]-1)*3+1]};
pair<int,int>y={ds[(val[n*n]-1)*3+2],dc[(val[n*n]-1)*3+2]};
pair<int,int>z={ds[(val[n*n]-1)*3+3],dc[(val[n*n]-1)*3+3]};
pair<int,int>Ans=min({x,y,z});
fout<<Ans.first<<' '<<Ans.second;
return 0;
}

浙公网安备 33010602011771号