强连通缩点 求最短路:
http://acm.sdut.edu.cn/sdutoj/problem.php?action=showproblem&problemid=3262
#include <bits/stdc++.h>
using namespace std;
const int maxn=1e5+4;
int dfn[maxn], low[maxn] ,instack[maxn], belong[maxn] ;
int stap[maxn],Stop,Bcnt,Dindex;
int n,m,flag;
struct edge{
int to;
};
vector<edge> E[maxn];
vector<edge> E2[maxn];
void tarjan(int i){
int j;
dfn[i]=low[i]=++Dindex;
instack[i]=1;
stap[++Stop]=i;
for( int k=0;k<E[i].size();k++ ){
j=E[i][k].to;
if( !dfn[j] ){
tarjan(j);
if( low[j]<low[i] )
low[i]=low[j];
}
else if( instack[j] &&dfn[j]< low[i] )
low[i]=dfn[j];
}
if( dfn[i]==low[i] ){
Bcnt++;
do{
j=stap[Stop--];
instack[j]=0;
belong[j]=Bcnt;
}
while( j!=i );
}
}
void solve(){
int i;
Stop=Bcnt=Dindex=0;
memset(dfn,0,sizeof(dfn));
memset(instack,0,sizeof(instack));
memset(belong,0,sizeof(belong));
memset(low,0,sizeof(low));
for(int i=0;i<n;i++){
if(!dfn [i] ) tarjan(i);
}
}
void init(){
for(int i=0;i<=n;i++){
E[i].clear();
E2[i].clear();
}
}
int dfs(int now){
if( now==belong[n-1] ){
flag=1;return 0;
}
int ans=1e9;
for(int i=0;i< E2[now].size();i++ )ans=min( ans,dfs(E2[now][i].to)+1 );
return ans;
}
int main(){
int t;
cin>>t;
while(t--){
scanf("%d%d",&n,&m);
init();
for(int i=0;i<m;i++){
int x,y;
scanf("%d%d",&x,&y);
E[x].push_back( edge{y} );
//E[y].push_back( edge{x} );
}
solve();
for(int i=0;i<n;i++){
for(int j=0;j< E[i].size();j++ ){
if( belong[i]!=belong[ E[i][j].to ] )
E2[belong[i] ].push_back( edge{ belong[ E[i][j].to ] } );
}
}
flag=0;
int ans=dfs( belong[0] );
if(flag) printf("%d\n",ans);
else puts("-1");
}
return 0;
}