dijk template
#include<iostream>
#include<climits>
#include<cmath>
#include<queue>
#include<vector>
#define ll long long
struct Node{
int to,far;
};
std::vector<ll>dijk(std::vector<std::vector<Node>>G,int n,int start){
std::vector<ll>dist(n+1,INT_MAX);
std::vector<bool>vis(n+1,0);
std::priority_queue<std::pair<ll,ll>,std::vector<std::pair<ll,ll>>,std::greater<std::pair<ll,ll>>>q;
q.push(std::make_pair(0,start));
dist[start]=0;
while(q.size()){
ll from=q.top().second;
q.pop();
if(vis[from]){
continue;
}
vis[from]=1;
for(auto i:G[from]){
if(dist[i.to]>dist[from]+i.far){
dist[i.to]=dist[from]+i.far;
q.push(std::make_pair(dist[i.to],i.to));
}
}
}
return dist;
}
spfa template
#include <iostream>
#include <climits>
#include <cmath>
#include <queue>
#include <vector>
#define ll long long
struct Node
{
ll to, far;
};
//此程序判断有没有环。如果只想求最短路,将函数类型改成std::vector<ll>,并且在函数末尾 return dist
//如果要求最长路,则std::vector<ll> dist(n + 1, INT_MAX);-> std::vector<ll> dist(n + 1, INT_MIN);
// dist[i.to] > dist[u] + i.far-> dist[i.to] < dist[u] + i.far
bool spfa(std::vector<std::vector<Node>> G, int n, int start)
{
std::vector<ll> viscnt(n+1,0);
std::vector<ll> dist(n + 1, INT_MAX);
std::vector<bool> inqueue(n+1,0);
std::queue<int> q;
dist[start] = 0;
viscnt[start]=1;
q.push(start);
inqueue[start]=1;
while (q.size())
{
int u = q.front();
q.pop();
inqueue[u]=0;
for (auto i : G[u])
{
if (dist[i.to] > dist[u] + i.far)
{
dist[i.to] = dist[u] + i.far;
if(!inqueue[i.to]){
if(viscnt[i.to]==n){
return 1;
}
q.push(i.to);
viscnt[i.to]++;
inqueue[i.to]=1;
}
}
}
}
return 0;
}
floyd
#include<iostream>
#include<climits>
#include<cstring>
#include<queue>
#include<vector>
#define infinity 0x3f3f3f3f
#define N 105
int n,m,G[N][N],dist[N][N];
int main(){
memset(dist,infinity,sizeof(dist));
std::cin>>n>>m;
for(int i=1;i<=m;i++){
int a,b,c;
std::cin>>a>>b>>c;
G[a][b]=G[b][a]=c;
}
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
if(i==j){
G[i][j]=0;
}else if(G[i][j]){
dist[i][j]=G[i][j];
}
}
}
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
for(int k=1;k<=n;k++){
if(dist[j][k]>dist[j][i]+dist[i][k]){
dist[j][k]=dist[j][i]+dist[i][k];
}
}
}
}
int res=INT_MIN;
for(int i=1;i<=n;i++){
if(dist[1][i]==infinity){
std::cout<<-1;
return 0;
}else{
res=std::max(res,dist[1][i]);
}
}
std::cout<<res;
}
dijk
#include<iostream>
#include<climits>
#include<cmath>
#include<queue>
#include<vector>
#define ll long long
struct Node{
int to,far;
};
std::vector<ll>dijk(std::vector<std::vector<Node>>G,int n,int start){
std::vector<ll>dist(n+1,INT_MAX);
std::vector<bool>vis(n+1,0);
std::priority_queue<std::pair<ll,ll>,std::vector<std::pair<ll,ll>>,std::greater<std::pair<ll,ll>>>q;
q.push(std::make_pair(0,start));
dist[start]=0;
while(q.size()){
ll from=q.top().second;
q.pop();
if(vis[from]){
continue;
}
vis[from]=1;
for(auto i:G[from]){
if(dist[i.to]>dist[from]+i.far){
dist[i.to]=dist[from]+i.far;
q.push(std::make_pair(dist[i.to],i.to));
}
}
}
return dist;
}
int main(){
int n,m;
std::cin>>n>>m;
std::vector<std::vector<Node>>G(n+1);
for(int i=0;i<m;i++){
int from,to,far;
std::cin>>from>>to>>far;
G[from].push_back(Node{to,far});
G[to].push_back(Node{from, far});
}
std::vector<ll>f=dijk(G,n,1);
ll res=INT_MIN;
for(int i=1;i<=n;i++){
res=std::max(res,f[i]);
}
if(res==INT_MIN)std::cout<<-1;
else std::cout<<res;
}
堆优化dijk
#include<iostream>
#include<climits>
#include<cmath>
#include<queue>
#include<vector>
#define ll long long
#define N 105
struct Node{
int to,far;
};
int cnt[N];
std::vector<ll>dijk(std::vector<std::vector<Node>>G,int n,int start){
std::vector<ll>dist(n+1,INT_MAX);
std::vector<bool>vis(n+1,0);
std::priority_queue<std::pair<ll,ll>,std::vector<std::pair<ll,ll>>,std::greater<std::pair<ll,ll>>>q;
q.push(std::make_pair(0,start));
dist[start]=0;
while(q.size()){
ll from=q.top().second;
q.pop();
if(vis[from]){
continue;
}
vis[from]=1;
for(auto i:G[from]){
if(dist[i.to]>dist[from]+i.far){
dist[i.to]=dist[from]+i.far;
q.push(std::make_pair(dist[i.to],i.to));
}
}
}
return dist;
}
int main(){
int n,p,c;
std::cin>>n>>p>>c;
std::vector<std::vector<Node>>G(p+1);
for(int i=1;i<=n;i++){
int x;
std::cin>>x;
cnt[x]++;
}
for(int i=1;i<=c;i++){
int u,v,w;
std::cin>>u>>v>>w;
G[u].push_back(Node{v,w});
G[v].push_back(Node{u,w});
}
int minn=1<<30;
for(int i=1;i<=p;i++){
std::vector<ll>dist=dijk(G,p,i);
int sum=0;
for(int j=1;j<=p;j++){
sum+=(dist[j]*cnt[j]);
}
minn=std::min(sum,minn);
}
std::cout<<minn;
}
floyd
#include<iostream>
#define infinity 0x3f3f3f3f
#define N 105
int G[N][N];
int main(){
int n,m;
std::cin>>n>>m;
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
if(i==j){
G[i][j]=0;
}else{
G[i][j]=infinity;
}
}
}
for(int i=1;i<=m;i++){
int u,v,w;
std::cin>>u>>v>>w;
G[u][v]=std::min(G[u][v],w);
G[v][u]=std::min(G[v][u],w);
}
for(int k=1;k<=n;k++){
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
if(G[i][j]>G[i][k]+G[k][j]){
G[i][j]=G[i][k]+G[k][j];
}
}
}
}
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
std::cout<<G[i][j]<<' ';
}
std::cout<<std::endl;
}
}
dijk
#include<iostream>
#include<climits>
#include<cmath>
#include<queue>
#include<vector>
#include<iomanip>
#define ll long long
struct Node{
ll to;
double far;
};
double distance(int x1,int y1,int x2,int y2){//二维平面上的点到另一个点的距离公式:sqrt((x1-x2)^2+(y1-y2)^2))
return 1.0*sqrt(1.0*(x1-x2)*(x1-x2)+(y1-y2)*1.0*(y1-y2)*1.0);
}
std::vector<double>dijk(std::vector<std::vector<Node>>G,int n,int start){
std::vector<double>dist(n+1,INT_MAX);
std::vector<bool>vis(n+1,0);
std::priority_queue<std::pair<double,double>,std::vector<std::pair<double,double>>,std::greater<std::pair<double,double>>>q;
q.push(std::make_pair(0,start));
dist[start]=0;
while(q.size()){
ll from=q.top().second;
q.pop();
if(vis[from]){
continue;
}
vis[from]=1;
for(auto i:G[from]){
if(dist[i.to]>dist[from]+i.far){
dist[i.to]=dist[from]+i.far;
q.push(std::make_pair(dist[i.to],i.to));
}
}
}
return dist;
}
int x[105],y[105];
int main(){
int n;
std::cin>>n;
std::vector<std::vector<Node>>G(n+1);
for(int i=1;i<=n;i++){
std::cin>>x[i]>>y[i];
}
int m;
std::cin>>m;
for(int i=1;i<=m;i++){
int u,v;
std::cin>>u>>v;
double w=distance(x[u],y[u],x[v],y[v]);
G[u].push_back(Node{v,w});
G[v].push_back(Node{u,w});
}
int s,t;
std::cin>>s>>t;
std::vector<double>f=dijk(G,n,s);
std::cout<<std::fixed<<std::setprecision(2)<<f[t];
}
dijk
#include<iostream>
#include<climits>
#include<cmath>
#include<queue>
#include<vector>
#define ll long long
struct Node{
ll to,far;
};
std::vector<ll>dijk(std::vector<std::vector<Node>>G,int n,int start){
std::vector<ll>dist(n+1,INT_MAX);
std::vector<bool>vis(n+1,0);
std::priority_queue<std::pair<ll,ll>,std::vector<std::pair<ll,ll>>,std::greater<std::pair<ll,ll>>>q;
q.push(std::make_pair(0,start));
dist[start]=0;
while(q.size()){
ll from=q.top().second;
q.pop();
if(vis[from]){
continue;
}
vis[from]=1;
for(auto i:G[from]){
if(dist[i.to]>std::max(dist[from],i.far)){
dist[i.to]=std::max(dist[from],i.far);
q.push(std::make_pair(dist[i.to],i.to));
}
}
}
return dist;
}
int main(){
int n,m,s,t;
std::cin>>n>>m>>s>>t;
std::vector<std::vector<Node>>G(n+1);
for(int i=1;i<=m;i++){
int u,v,w;
std::cin>>u>>v>>w;
G[u].push_back(Node{v,w});
G[v].push_back(Node{u,w});
}
std::vector<ll>f=dijk(G,n,s);
std::cout<<f[t];
}
dijk
#include<iostream>
#include<climits>
#include<cmath>
#include<queue>
#include<vector>
#define ll long long
struct Node{
int to,far;
};
std::vector<ll>dijk(std::vector<std::vector<Node>>G,int n,int start){
std::vector<ll>dist(n+1,INT_MAX);
std::vector<bool>vis(n+1,0);
std::priority_queue<std::pair<ll,ll>,std::vector<std::pair<ll,ll>>,std::greater<std::pair<ll,ll>>>q;
q.push(std::make_pair(0,start));
dist[start]=0;
while(q.size()){
ll from=q.top().second;
q.pop();
if(vis[from]){
continue;
}
vis[from]=1;
for(auto i:G[from]){
if(dist[i.to]>dist[from]+i.far){
dist[i.to]=dist[from]+i.far;
q.push(std::make_pair(dist[i.to],i.to));
}
}
}
return dist;
}
int main(){
int n,m;
std::cin>>n>>m;
std::vector<std::vector<Node>>G(n+1);
std::vector<std::vector<Node>>G2(n+1);
for(int i=1;i<=m;i++){
int u,v,w;
std::cin>>u>>v>>w;
G[u].push_back(Node{v,w});
G2[v].push_back(Node{u,w});
}
std::vector<ll>f=dijk(G,n,1);
std::vector<ll>f2=dijk(G2,n,1);
ll res=0;
for(int i=1;i<=n;i++){
res+=f[i]+f2[i];
}
std::cout<<res;
}
dijk
#include<iostream>
#include<climits>
#include<cmath>
#include<queue>
#include<vector>
#include<cstring>
#define ll long long
#define N 10005
struct Node{
int to,far;
};
std::vector<ll>dijk(std::vector<std::vector<Node>>G,int n,int start){
std::vector<ll>dist(n+1,INT_MAX);
std::vector<bool>vis(n+1,0);
std::priority_queue<std::pair<ll,ll>,std::vector<std::pair<ll,ll>>,std::greater<std::pair<ll,ll>>>q;
q.push(std::make_pair(0,start));
dist[start]=0;
while(q.size()){
ll from=q.top().second;
q.pop();
if(vis[from]){
continue;
}
vis[from]=1;
for(auto i:G[from]){
if(dist[i.to]>dist[from]+i.far){
dist[i.to]=dist[from]+i.far;
q.push(std::make_pair(dist[i.to],i.to));
}
}
}
return dist;
}
int main(){
int n,m,s;
std::cin>>n>>m>>s;
std::vector<std::vector<Node>>G(n+1);
for(int i=1;i<=m;i++){
int u,v,w;
std::cin>>u>>v>>w;
G[u].push_back(Node{v,w});
}
std::vector<ll>dist=dijk(G,n,s);
for(int i=1;i<=n;i++){
std::cout<<dist[i]<<' ';
}
}
dijk
#include<iostream>
#include<climits>
#include<cmath>
#include<map>
#include<queue>
#include<vector>
#include<cstring>
#define ll long long
#define N 10005
struct Node{
int to,far;
};
std::vector<ll>dijk(std::vector<std::vector<Node>>G,int n,int start){
std::vector<ll>dist(n+1,INT_MAX);
std::vector<bool>vis(n+1,0);
std::priority_queue<std::pair<ll,ll>,std::vector<std::pair<ll,ll>>,std::greater<std::pair<ll,ll>>>q;
q.push(std::make_pair(0,start));
dist[start]=0;
while(q.size()){
ll from=q.top().second;
q.pop();
if(vis[from]){
continue;
}
vis[from]=1;
for(auto i:G[from]){
if(dist[i.to]>dist[from]+i.far){
dist[i.to]=dist[from]+i.far;
q.push(std::make_pair(dist[i.to],i.to));
}
}
}
return dist;
}
std::map<std::pair<int,int>,int>mp;
int main(){
int n,m,s;
std::cin>>n>>m>>s;
std::vector<std::vector<Node>>G(n+1);
for(int i=1;i<=m;i++){
int u,v,w;
std::cin>>u>>v>>w;
G[u].push_back(Node{v,w});
}
std::vector<ll>dist=dijk(G,n,s);
for(int i=1;i<=n;i++){
std::cout<<dist[i]<<' ';
}
}
dijk
#include<iostream>
#include<climits>
#include<cmath>
#include<queue>
#include<vector>
#define ll long long
struct Node{
int to,far;
};
std::vector<ll>dijk(std::vector<std::vector<Node>>G,int n,int start){
std::vector<ll>dist(n+1,INT_MAX);
std::vector<bool>vis(n+1,0);
std::priority_queue<std::pair<ll,ll>,std::vector<std::pair<ll,ll>>,std::greater<std::pair<ll,ll>>>q;
q.push(std::make_pair(0,start));
dist[start]=0;
while(q.size()){
ll from=q.top().second;
q.pop();
if(vis[from]){
continue;
}
vis[from]=1;
for(auto i:G[from]){
if(dist[i.to]>dist[from]+i.far){
dist[i.to]=dist[from]+i.far;
q.push(std::make_pair(dist[i.to],i.to));
}
}
}
return dist;
}
int main(){
int n,m,b;
std::cin>>n>>m>>b;
std::vector<std::vector<Node>>G(n+1);
for(int i=1;i<=m;i++){
int u,v,w;
std::cin>>u>>v>>w;
G[u].push_back(Node{v,w});
G[v].push_back(Node{u,w});
}
std::vector<ll>f=dijk(G,n,1);
for(int i=1;i<=b;i++){
int s,t;
std::cin>>s>>t;
std::cout<<f[s]+f[t]<<std::endl;
}
}
spfa
#include <iostream>
#include <climits>
#include <cmath>
#include <queue>
#include <vector>
#define ll long long
struct Node
{
ll to, far;
};
bool spfa(std::vector<std::vector<Node>> G, int n, int start)
{
std::vector<ll> viscnt(n+1,0);
std::vector<ll> dist(n + 1, INT_MAX);
std::vector<bool> inqueue(n+1,0);
std::queue<int> q;
dist[start] = 0;
viscnt[start]=1;
q.push(start);
inqueue[start]=1;
while (q.size())
{
int u = q.front();
q.pop();
inqueue[u]=0;
for (auto i : G[u])
{
if (dist[i.to] > dist[u] + i.far)
{
dist[i.to] = dist[u] + i.far;
if(!inqueue[i.to]){
if(viscnt[i.to]==n){
return 1;
}
q.push(i.to);
viscnt[i.to]++;
inqueue[i.to]=1;
}
}
}
}
return 0;
}
int main()
{
int t;
std::cin >> t;
while (t--)
{
int n, m;
std::cin >> n >> m;
std::vector<std::vector<Node>> G(n + 1);
for (int i = 1; i <= m; i++)
{
int a, b, c;
std::cin >> a >> b >> c;
if (c >= 0)
{
G[a].push_back(Node{b, c});
G[b].push_back(Node{a, c});
}
else
{
G[a].push_back(Node{b, c});
}
}
if(spfa(G,n,1))std::cout<<"YES\n";
else std::cout<<"NO\n";
}
}
spfa
#include <iostream>
#include <climits>
#include <cmath>
#include <queue>
#include <vector>
#define ll long long
struct Node
{
ll to, far;
};
int d;
std::vector<ll> spfa(std::vector<std::vector<Node>> G, int n, int start)
{
std::vector<ll> viscnt(n + 1, 0);
std::vector<ll> dist(n + 1, INT_MIN);
std::vector<bool> inqueue(n + 1, 0);
std::queue<int> q;
dist[start] = d;
viscnt[start] = 1;
q.push(start);
inqueue[start] = 1;
while (q.size())
{
int u = q.front();
q.pop();
inqueue[u] = 0;
for (auto i : G[u])
{
if (dist[i.to] < dist[u] + i.far)
{
dist[i.to] = dist[u] + i.far;
if (!inqueue[i.to])
{
if (viscnt[i.to] == n)
{
std::cout<<-1;
exit(0);
}
q.push(i.to);
viscnt[i.to]++;
inqueue[i.to] = 1;
}
}
}
}
return dist;
}
int main()
{
int p,c,f,s;
std::cin>>d>>p>>c>>f>>s;
std::vector<std::vector<Node>>G(c+1);
for(int i=1;i<=p;i++){
int a,b;
std::cin>>a>>b;
G[a].push_back(Node{b,d});
}
for(int i=1;i<=f;i++){
int a,b,_c;
std::cin>>a>>b>>_c;
G[a].push_back(Node{b,d-_c});
}
std::vector<ll>dist=spfa(G,c,s);
ll res1=INT_MIN;
for(ll i=1;i<=c;i++){
res1=std::max(res1,dist[i]);
}
std::cout<<res1;
}
dijk
#include<iostream>
#include<climits>
#include<cmath>
#include<queue>
#include<vector>
#define ll long long
struct Node{
int to,far;
};
std::vector<ll>dijk(std::vector<std::vector<Node>>G,int n,int start){
std::vector<ll>dist(n+1,INT_MAX);
std::vector<bool>vis(n+1,0);
std::priority_queue<std::pair<ll,ll>,std::vector<std::pair<ll,ll>>,std::greater<std::pair<ll,ll>>>q;
q.push(std::make_pair(0,start));
dist[start]=0;
while(q.size()){
ll from=q.top().second;
q.pop();
if(vis[from]){
continue;
}
vis[from]=1;
for(auto i:G[from]){
if(dist[i.to]>dist[from]+i.far){
dist[i.to]=dist[from]+i.far;
q.push(std::make_pair(dist[i.to],i.to));
}
}
}
return dist;
}
int main(){
int f,p,c,m;
std::cin>>f>>p>>c>>m;
std::vector<std::vector<Node>>G(f+1);
for(int i=1;i<=p;i++){
int u,v,w;
std::cin>>u>>v>>w;
G[u].push_back(Node{v,w});
G[v].push_back(Node{u,w});
}
std::vector<ll>dist=dijk(G,f,1);
int ans=0;
std::vector<ll>res;
for(int i=1;i<=c;i++){
ll x;
std::cin>>x;
if(dist[x]<=m){
ans++;
res.push_back(i);
}
}
std::cout<<ans<<'\n';
for(auto i:res){
std::cout<<i<<'\n';
}
}
dijk(求最短路和最短路径的条数)
#include<iostream>
#include<climits>
#include<cmath>
#include<queue>
#include<map>
#include<vector>
#define ll long long
struct Node{
int to,far;
};
std::vector<ll>dijk(std::vector<std::vector<Node>>G,int n,int start){
std::vector<ll>dist(n+1,INT_MAX);
std::vector<ll>cnt(n+1,0);
std::vector<bool>vis(n+1,0);
std::priority_queue<std::pair<ll,ll>,std::vector<std::pair<ll,ll>>,std::greater<std::pair<ll,ll>>>q;
q.push(std::make_pair(0,1));
dist[start]=0;
cnt[start]=1;
while(q.size()){
ll from=q.top().second;
q.pop();
if(vis[from]){
continue;
}
vis[from]=1;
for(auto i:G[from]){
if(dist[i.to]>dist[from]+i.far){
dist[i.to]=dist[from]+i.far;
cnt[i.to]=cnt[from];
q.push(std::make_pair(dist[i.to],i.to));
}else if(dist[i.to]==dist[from]+i.far){
cnt[i.to]+=cnt[from];
}
}
}
return {dist[n],cnt[n]};
}
std::map<std::pair<int,int>,int>mp;
int main(){
int n,m;
std::cin>>n>>m;
std::vector<std::vector<Node>>G(n+1);
for(int i=1;i<=m;i++){
int u,v,w;
std::cin>>u>>v>>w;
if(mp[{u,v}]==w)continue;
G[u].push_back(Node{v,w});
mp[{u,v}]=w;
}
std::vector<ll>f=dijk(G,n,1);
if(f[0]==INT_MAX){
std::cout<<"No answer";
}else{
std::cout<<f[0]<<' '<<f[1];
}
}
spfa(求有没有负环并且求最短路)
#include <iostream>
#include <climits>
#include <cmath>
#include <queue>
#include <vector>
#define ll long long
struct Node
{
ll to, far;
};
//此程序判断有没有环。如果只想求最短路,将函数类型改成std::vector<ll>,并且在函数末尾 return dist
//如果要求最长路,则std::vector<ll> dist(n + 1, INT_MAX);-> std::vector<ll> dist(n + 1, INT_MIN);
// dist[i.to] > dist[u] + i.far-> dist[i.to] < dist[u] + i.far
std::vector<ll> spfa(std::vector<std::vector<Node>> G, int n, int start)
{
std::vector<ll> viscnt(n+1,0);
std::vector<ll> dist(n + 1, INT_MAX);
std::vector<bool> inqueue(n+1,0);
std::queue<int> q;
dist[start] = 0;
viscnt[start]=1;
q.push(start);
inqueue[start]=1;
while (q.size())
{
int u = q.front();
q.pop();
inqueue[u]=0;
for (auto i : G[u])
{
if (dist[i.to] > dist[u] + i.far)
{
dist[i.to] = dist[u] + i.far;
if(!inqueue[i.to]){
if(viscnt[i.to]==n){
std::cout<<"Forever love";
exit(0);
}
q.push(i.to);
viscnt[i.to]++;
inqueue[i.to]=1;
}
}
}
}
return dist;
}
int main(){
int n,m;
std::cin>>n>>m;
std::vector<std::vector<Node>>G(n+1);
for(int i=1;i<=m;i++){
int u,v,w;
std::cin>>u>>v>>w;
G[u].push_back(Node{v,-w});
}
std::vector<ll> f = spfa(G, n, 1);
std::vector<ll> ff = spfa(G,n,n);
std::cout<<std::min(f[n],ff[1]);
}
dijk
#include<iostream>
#include<climits>
#include<cmath>
#include<queue>
#include<vector>
#define ll long long
struct Node{
ll to,far;
};
std::vector<ll>dijk(std::vector<std::vector<Node>>G,int n,int start){
std::vector<ll>dist(n+1,INT_MAX);
std::vector<bool>vis(n+1,0);
std::priority_queue<std::pair<ll,ll>,std::vector<std::pair<ll,ll>>,std::greater<std::pair<ll,ll>>>q;
q.push(std::make_pair(0,start));
dist[start]=0;
while(q.size()){
ll from=q.top().second;
q.pop();
if(vis[from]){
continue;
}
vis[from]=1;
for(auto i:G[from]){
if(dist[i.to]>dist[from]+i.far){
dist[i.to]=dist[from]+i.far;
q.push(std::make_pair(dist[i.to],i.to));
}
}
}
return dist;
}
std::vector<int>work(std::string s){
std::vector<int>list;
int t=0;
for(int i=0;i<s.size();i++){
if(s[i]=='\r'){
continue;
}
if(s[i]==' '){
list.push_back(t);
t=0;
}else{
t=t*10+s[i]-'0';
}
}if(t!=0){
list.push_back(t);
}
return list;
}
int main(){
int m,n;
std::cin>>m>>n;
std::vector<std::vector<Node>>G(n+1);
std::string s;
getline(std::cin, s);
for(int i=1;i<=m;i++){
getline(std::cin,s);
std::vector<int>list=work(s);
for(int j=0;j<list.size();j++){
for(int k=j+1;k<list.size();k++){
G[list[j]].push_back(Node{list[k],1});
}
//
}
}
std::vector<ll>dist=dijk(G,n,1);
if(dist[n]>INT_MAX or dist[n]==INT_MAX)std::cout<<"NO";
else std::cout<<dist[n]-1;
}