l
i
n
k
\textcolor{pink}{link}
link
分析:
不用分层图 暴力做法就是 连边跑
D
i
j
k
s
t
r
a
Dijkstra
Dijkstra
但问题在于建图
O
(
n
2
)
O(n^2)
O(n2) 那可以直接用给的矩阵 用一个新表记录
p
i
,
j
p_{i,j}
pi,j品种
i
i
i 第
j
j
j个奶牛的位置
对于松弛过的点 就可以不松弛了 然后跑小根堆优化
D
i
j
k
s
t
r
a
Dijkstra
Dijkstra
CODE:
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<queue>
#pragma GCC optimize(2)
#define reg register
using namespace std;
const int N=5e4+5,M=55;
int n,k,to[M][M],p[M][N],vis[N],tot[N],dis[N],a[N];
char s[M];
priority_queue<pair<int,int>,vector<pair<int,int> >,greater<pair<int,int> > > q;
void Dij(int st)
{
dis[st]=0;
q.push(make_pair(0,st));
while(!q.empty())
{
int x=q.top().second;
q.pop();
if(vis[x]) continue;
vis[x]=1;
for(reg int i=1;i<=k;i++)
if(to[a[x]][i])
for(reg int j=1;j<=tot[i];j++)
{
int qwq=p[i][j];
while(vis[qwq]&&tot[i]>1) swap(p[i][tot[i]--],qwq),p[i][j]=qwq;
if(!vis[qwq]&&dis[qwq]>dis[x]+abs(x-qwq))
{
dis[qwq]=dis[x]+abs(x-qwq);
q.push(make_pair(dis[qwq],qwq));
}
}
}
}
int main(){
scanf("%d%d",&n,&k);
for(reg int i=1,x;i<=n;i++)
{
scanf("%d",&x);
a[i]=x;
p[x][++tot[x]]=i;
}
for(reg int i=1;i<=k;i++)
{
scanf("%s",s+1);
for(reg int j=1;j<=k;j++)
if(s[j]=='1') to[i][j]=1;
}
memset(dis,0x3f,sizeof dis);
Dij(1);
int ans=(dis[n]==0x3f3f3f3f)?-1:dis[n];
printf("%d",ans);
return 0;
}