比赛 |
2025暑期集训第5场图论专场 |
评测结果 |
AAAEEEEEEEEEE |
题目名称 |
Telephone |
最终得分 |
23 |
用户昵称 |
会挽弯弓满月 |
运行时间 |
1.523 s |
代码语言 |
C++ |
内存使用 |
4.92 MiB |
提交时间 |
2025-07-09 11:59:42 |
显示代码纯文本
#include <bits/stdc++.h>
#define pb push_back
using namespace std;
const int N=5e4+10,K=60,MAX=1e9;
int read(){
int x=0,f=1;
char c=getchar();
while(c<48||c>57){
if(c==45) f=-1;
c=getchar();
}
while(c>=48&&c<=57){
x=x*10+c-48;
c=getchar();
}
return f*x;
}
int n,k;
int b[N];
char s[K];
int g[K][K];
vector<int> a[N];
queue<int> q;
int dis[K];
void bfs(){
for(int i=2;i<=n;i++) dis[i]=MAX;
q.push(k+1);
int u,si1,si2,i,j;
int eu,ev;
bool vis;
while(!q.empty()){
u=q.front();q.pop();
for(int v=1;v<=k+2;v++){
if(!g[u][v]) continue;
vis=0;si1=a[u].size();si2=a[v].size();
i=0;j=0;
while(i<si1&&j<si2){
eu=a[u][i];ev=a[v][j];
if(dis[eu]+abs(eu-ev)<dis[ev]){
dis[ev]=dis[eu]+abs(eu-ev);
vis=1;
}
if(i==si1-1||eu>ev) j++;
else i++;
}
if(vis) q.push(v);
}
}
return;
}
int ans;
int main(){
freopen("telephone.in","r",stdin);
freopen("telephone.out","w",stdout);
n=read();k=read();
for(int i=1;i<=n;i++){
b[i]=read();
if(i==1||i==n) continue;
a[b[i]].pb(i);
}
a[k+1].pb(1);//初
a[k+2].pb(n);//末
for(int i=1;i<=k;i++){
scanf("%s",s+1);
for(int j=1;j<=k;j++){
g[i][j]=s[j]-48;
}
}
if(b[1]==b[n]&&g[b[1]][b[n]]==1){
printf("%d",n-1);
return 0;
}
for(int i=1;i<=k;i++){
if(g[b[1]][i]) g[k+1][i]=1;
if(g[i][b[n]]) g[i][k+2]=1;
}
b[1]=k+1;b[n]=k+2;
bfs();
if(dis[n]==MAX) ans=-1;
else ans=dis[n];
printf("%d",ans);
return 0;
}