比赛 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;
}