解题思路
最后跑从1到n的最短路即可
(样例的图:超级丑但是是对的)
代码
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<iomanip>
#include<cstring>
#include<cmath>
#include<map>
#include<queue>
#include<set>
#define ll long long
#define ldb long double
using namespace std;
const int maxn=2147483600;
int n,k,K,w[500010],b[60][60],head[3500010],dis[3500010],v[3500010];
char s[60];
struct c {
int x,next,w;
}a[8000010];
void add(int x,int y,int v) {
a[++k]=(c){y,head[x],v};
head[x]=k;
}
int get(int x,int y) {
return (x-1)*n+y;
}
void SPFA() {
memset(dis,0x3f3f3f3f,sizeof(dis));
queue<int>q;
q.push(1);
dis[1]=0,v[1]=1;
while(!q.empty()) {
int x=q.front();q.pop();v[x]=0;
for(int i=head[x]; i; i=a[i].next) {
int y=a[i].x;
if(dis[y]>dis[x]+a[i].w) {
dis[y]=dis[x]+a[i].w;
if(!v[y]) {
v[y]=1;
q.push(y);
}
}
}
}
}
int main() {
scanf("%d%d",&n,&K);
for(int i=1; i<=n; i++)
scanf("%d",&w[i]);
for(int i=1; i<=K; i++) {
scanf("%s",s+1);
for(int j=1; j<=K; j++) {
b[i][j]=s[j]-'0';
}
}
for(int i=2; i<=K+1; i++) {
for(int j=2; j<=n; j++) {
add(get(i,j),get(i,j-1),1);
add(get(i,j-1),get(i,j),1);
}
}
for(int i=1; i<=K; i++) {
for(int j=1; j<=n; j++) {
if(b[i][w[j]])
add(get(i+1,j),j,0);
if(w[j]==i)
add(j,get(i+1,j),0);
}
}
SPFA();
if(dis[n]!=0x3f3f3f3f)printf("%d",dis[n]);
else printf("-1");
}
/*
8 4
4 1 1 2 4 3 4 1
0000
0010
0100
0010
*/