存反图,从终点dfs一遍,记录下无法到达的点。
然后枚举这些记录的点,把他们的出边所连的点也全部记录。
以上这些点都是无法在最短路中出现的。
所以把两个端点都没被记录的边加进图里,跑spfa、BFS什么的随意。
1 #include<cstdio> 2 #include<vector> 3 #include<cstring> 4 #include<queue> 5 using namespace std; 6 #define N 10001 7 vector<int>G[N],rG[N]; 8 queue<int>q; 9 typedef vector<int>::iterator ITER; 10 int n,m,from,can[N],to,dis[N],x[200001],y[200001]; 11 bool inq[N]; 12 void dfs(int U) 13 { 14 can[U]=1; 15 for(ITER it=rG[U].begin();it!=rG[U].end();it++) 16 if(!can[*it]) 17 dfs(*it); 18 } 19 void spfa(const int &s) 20 { 21 memset(dis,0x7f,sizeof(dis)); dis[s]=0; 22 q.push(s); inq[s]=1; 23 while(!q.empty()) 24 { 25 int U=q.front(); 26 for(ITER it=G[U].begin();it!=G[U].end();it++) 27 if(dis[*it]>dis[U]+1) 28 { 29 dis[*it]=dis[U]+1; 30 if(!inq[*it]) 31 { 32 q.push(*it); 33 inq[*it]=1; 34 } 35 } 36 q.pop(); inq[U]=0; 37 } 38 } 39 int main() 40 { 41 scanf("%d%d",&n,&m); 42 for(int i=1;i<=m;i++) 43 { 44 scanf("%d%d",&x[i],&y[i]); 45 rG[y[i]].push_back(x[i]); 46 } 47 scanf("%d%d",&from,&to); dfs(to); 48 for(int i=1;i<=n;i++) 49 if(!can[i]) 50 for(ITER it=rG[i].begin();it!=rG[i].end();it++) 51 can[*it]=0; 52 for(int i=1;i<=m;i++) 53 if(can[x[i]]&&can[y[i]]) 54 G[x[i]].push_back(y[i]); 55 spfa(from); 56 printf("%d ",dis[to]>2000000000 ? -1 : dis[to]); 57 return 0; 58 }