先用原图建反向边,其中j%2==1的是原图,==2的是反向图
先从结束点开始反向bfs找所有可以到达结束点的点
在处理出所有出边都是可达终点的点,b【i】=true
再正向bfs,直到找到终点,然后结束函数,返回输出ans【t】即可
#include<cstdio> #include<algorithm> #include<cstdlib> #include<iostream> #include<cstring> #include<string> #include<cmath> #include<cctype> #include<queue> using namespace std; const int maxn=10009; const int maxm=500009; int ans[maxn],n,m,edge[maxm],head[maxn],tot,s,t,next[maxm]; bool b[maxn]={false},y[maxn]={false},yy[maxn]={false}; void addedge(int from,int to) { tot++; edge[tot]=to;next[tot]=head[from];head[from]=tot; tot++; edge[tot]=from;next[tot]=head[to];head[to]=tot; } queue<int>q; queue<int>qq; void dfs1() { qq.push(t); b[t]=true; while (!qq.empty()) { int u=qq.front();qq.pop(); y[u]=true; for (int i=head[u];i;i=next[i]) if (i%2==0) { int v=edge[i]; if (!b[v]) { b[v]=true; qq.push(v); } } } } void bfs() { q.push(s); ans[s]=0;yy[s]=true; while (!q.empty()) { int u=q.front(); q.pop(); for (int i=head[u];i;i=next[i]) if (i%2==1) { int v=edge[i]; if (v==t) { yy[t]=true; ans[t]=ans[u]+1; return ; } if (b[v]&&!yy[v]) { yy[v]=true; ans[v]=ans[u]+1; q.push(v); } } } } int main() { scanf("%d%d",&n,&m); for (int i=1;i<=m;i++) { int x,y; scanf("%d%d",&x,&y); if (x!=y)addedge(x,y); } scanf("%d%d",&s,&t); dfs1(); memset(b,true,sizeof(b)); for (int i=1;i<=n;i++) { for (int j=head[i];j;j=next[j]) if (j%2==1) { int v=edge[j]; if (!y[v]) { b[i]=false; break; } } } bfs(); if (yy[t])printf("%d",ans[t]);else printf("-1"); return 0; }