用的是双端队列,Luogu WA 70pts,AcWing WA 10/13,谢谢各位大佬
// 2023/
#include<iostream>
#include<string>
#include<deque>
#include<cstring>
#define maxn 101
using namespace std;
struct Edge{ int v,nxt,idx; }edge[maxn*10];
int head[maxn],cnt,n,m,dis[maxn];
bool vis[maxn];
void add(int u,int v,int idx){ edge[++cnt].v=v,edge[cnt].idx=idx,edge[cnt].nxt=head[u],head[u]=cnt; }
string s;
void work(int idx){ // 处理读入
int len=s.length();
int u=0,v=0,a=0; bool flag=false,flag2=false;
for (int i=0;i<=len;i++)
// 这里写 <=len 会越界,但正是利用越界可以得到非数字字符,
// 而下面建边的触发条件就是由数字字符转为非数字字符,若没有非数字字符则无法建边
if ('0'<=s[i]&&s[i]<='9')
if (flag) a=a*10+(s[i]-'0');
else { a=s[i]-'0',flag=true; }
else if (flag){
flag=false;
if (flag2==false) v=a,a=0,flag2=true;
else {
u=v,v=a; add(u,v,idx);
// cout<<u<<"-->"<<v<<endl;
}
}
}
void bfs(){
deque <pair<int,int> > q;
memset(dis,0x3f,sizeof dis);
dis[1]=0,q.push_front(make_pair(1,0));
while (!q.empty()){
int u=q.front().first,id=q.front().second; q.pop_front();
// if (vis[u]) continue;
vis[u]=true;
for (int i=head[u];i;i=edge[i].nxt){
int v=edge[i].v,idx=edge[i].idx,w=(id!=0 && idx!=id);
if (dis[v]>dis[u]+w ){
dis[v]=dis[u]+w;
if (vis[v]) continue;
if (w) q.push_back(make_pair(v,idx));
else q.push_front(make_pair(v,idx));
// printf("u:%d v:%d idx:%d w:%d\n",u,v,idx,w);
}
}
}
}
int main(){
cin>>m>>n;
for (int i=0;i<=m;i++){ // 多输入一次:吞掉上一行的换行符号
getline(cin,s);
work(i);
s="";
}
bfs();
// for (int i=1;i<=n;i++) cout<<dis[i]<<' ';
if (dis[n]==0x3f3f3f3f) cout<<"NO";
else cout<<dis[n];
return 0;
}
/*
in:
3 7
6 7
4 7 3 6
2 1 3 5
out:
*/