比赛 |
2025暑期集训第5场图论专场 |
评测结果 |
AAAAAAAAAAAAA |
题目名称 |
Telephone |
最终得分 |
100 |
用户昵称 |
左清源 |
运行时间 |
1.227 s |
代码语言 |
C++ |
内存使用 |
62.64 MiB |
提交时间 |
2025-07-09 10:16:14 |
显示代码纯文本
#include <bits/stdc++.h>
using namespace std;
const int N=5e4+10;
const int V=3e6,E=1e7+10;
// k 条线,线与线之间连双向边,边长为 1
// 每个节点想对应线对应位置连单向边,长为 0
// 每条线向能交流的奶牛连单向边,长为 0
// 起点 1,终点 n
// 原图中的点 nk+i,第 k 条线上的第 j 个点 (k-1)n+j
// 点数:3e6,变数: 1e7--> 01 BFS O(n+m)
// 我补药写 01 BFS /kel/kel
int n,k,b[N],dis[V],mk[V];
int ver[V],to[E],nxt[E],val[E],idx,cnt;
char s[55][55];
deque<int>q;
void add(int x,int y,int z){
cnt++;
to[++idx]=y,nxt[idx]=ver[x],ver[x]=idx,val[idx]=z;
}
void BFS(int s){
memset(dis,0x3f,sizeof(dis));
q.push_front(s),dis[s]=0;
while(q.size()){
int x=q.front();q.pop_front();
if(mk[x])continue;mk[x]=1;
for(int i=ver[x];i;i=nxt[i]){
int y=to[i];
if(dis[y]>dis[x]+val[i]){
dis[y]=dis[x]+val[i];
if(val[i]==0)q.push_front(y);
else q.push_back(y);
}
}
}
return;
}
int main(){
freopen("telephone.in","r",stdin);
freopen("telephone.out","w",stdout);
scanf("%d %d",&n,&k);
for(int i=1;i<=n;i++){
scanf("%d",b+i);
}
for(int i=1;i<=k;i++){
scanf("%s",s[i]+1);
}
for(int i=1;i<=k;i++){
for(int j=1;j<n;j++){
add((i-1)*n+j,(i-1)*n+j+1,1);
add((i-1)*n+j+1,(i-1)*n+j,1);
}
for(int j=1;j<=n;j++){
if(s[i][b[j]]=='1')add((i-1)*n+j,n*k+j,0);
if(i==b[j])add(n*k+j,(i-1)*n+j,0);
}
}
BFS(n*k+1);
if(dis[n*k+n]>=0x3f3f3f3f)printf("-1\n");
else printf("%d\n",dis[n*k+n]);
return 0;
}