先用强联通分量缩点,然后深搜找最短路径就行了,
#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; }