先反向建边,这样以t为源点一遍bfs即可判断出哪个点不可以到达t点;
然后正向建边,以s为源点再一遍bfs计算距离;对于一个点u枚举其叶子结点v来判断u的子节点是否可以直接或间接到达t;
#include <bits/stdc++.h> #define cin std::ios::sync_with_stdio(false); cin #define cout std::ios::sync_with_stdio(false); cout using namespace std; struct littlestar{ int to; int nxt; }star[400010],star2[400010]; int head2[400010],cnt2; int head[400010],cnt; inline void add(int u,int v) { star[++cnt].to=v; star[cnt].nxt=head[u]; head[u]=cnt; } inline void add2(int u,int v) { star2[++cnt2].to=v; star2[cnt2].nxt=head2[u]; head2[u]=cnt2; } int f[200010]; int zhaobaba(int x) { if(f[x]==x){ return x; } return f[x]=zhaobaba(f[x]); } int n,m; int bo[100010]; int s,t; queue<int> q; int dis[100010],vis[100010]; void bfs() { q.push(t); bo[t]=1; while(q.size()){ int u=q.front(); q.pop(); for(register int i=head2[u];i;i=star2[i].nxt){ int v=star2[i].to; if(!bo[v]){ bo[v]=1; q.push(v); } } } } void bfs2() { while(q.size()) q.pop(); vis[s]=1; dis[s]=0; q.push(s); while(q.size()){ register int u=q.front(); q.pop(); bool lala=1; for(register int i=head[u];i;i=star[i].nxt){ int v=star[i].to; if(!bo[v]) lala=0; } if(lala==0) continue; for(register int i=head[u];i;i=star[i].nxt){ int v=star[i].to; if(!vis[v]){ vis[v]=1; dis[v]=dis[u]+1; q.push(v); } } } } int main() { cin>>n>>m; for(register int i=1;i<=m;i++){ int x,y; cin>>x>>y; add(x,y); add2(y,x); } cin>>s>>t; int goal=f[t]; bfs(); bfs2(); cout<<dis[t]; }