先用强联通分量缩点,然后深搜找最短路径就行了,
#include <bits/stdc++.h>
using namespace std;
const int max_V=100005;
vector<int>G[max_V];
vector<int>rG[max_V];
vector<int>vs;
int used[max_V];
int cmp[max_V],cnt[max_V],vis[max_V];
int V;
void dfs(int v)
{
used[v]=1;
for(int i=0; i<(int)G[v].size(); i++)
{
if(!used[G[v][i]])
dfs(G[v][i]);
}
vs.push_back(v);
}
void rdfs(int v,int k)
{
cnt[k]++;
used[v]=1;
cmp[v]=k;
for(int i=0; i<(int)rG[v].size(); i++)
{
if(!used[rG[v][i]])
rdfs(rG[v][i],k);
}
}
int Kosaraju()
{
int k=0;
memset(used,0,sizeof(used));
vs.clear();
for(int v=0; v<V; v++)
{
if(!used[v])dfs(v);
}
memset(used,0,sizeof(used));
for(int i=V-1; i>=0; i--)
{
if(!used[vs[i]])
{
rdfs(vs[i],k++);
}
}
return k;
}
int flag=0;
int dfs1(int u,int now)
{
if(used[u]!=-1)return used[u];
if(cmp[u]==cmp[V-1])
{flag=1;return now;}
int ans=100001;
for(int i=0;i<(int)G[u].size();i++)
{
int tmp=G[u][i];
if(vis[tmp])continue;
vis[tmp]=1;
ans=min(ans,dfs1(G[u][i],now+(cmp[u]==cmp[tmp]?0:1)));
vis[tmp]=0;
}
used[u]=ans;
return ans;
}
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
int m,x,y;
scanf("%d%d",&V,&m);
for(int i=0;i<V;i++)G[i].clear(),rG[i].clear();
memset(cnt,0,sizeof(cnt));
while(m--)
{
scanf("%d%d",&x,&y);
G[x].push_back(y);
rG[y].push_back(x);
}
Kosaraju();
if(cmp[0]==cmp[V-1])
{printf("0\n");
continue;}
memset(used,-1,sizeof(used));
memset(vis,0,sizeof(vis));
vis[0]=1;
flag=0;
dfs1(0,0);
if(flag==0)
{
printf("-1\n");
continue;
}
printf("%d\n",used[0]);
}
return 0;
}