我学习了题解的方法,先反向建边,判读能否到达终点,再正着跑了一遍dfs(题解里大多是bfs),但是我不知道为什么有4个点过不去,后来我又加了个df2,跑了两次dfs就过了,这是为什么?
#include<bits/stdc++.h>
using namespace std;
inline int read(){
int k=0;bool f=1;char ch=getchar();
while(!isdigit(ch)){if(ch=='-')f=0;ch=getchar();}
while(isdigit(ch)){k=(k<<1)+(k<<3)+(ch^48);ch=getchar();}
return f?k:-k;
}
const int N=1e4+2,M=2e5+2;
struct node{
int to,next;
}v[M],v1[M];
int h[M],cnt,h1[M],cnt1;
inline void add(int x,int y){
v[++cnt].to=y;
v[cnt].next=h[x];
h[x]=cnt;
}
inline void dda(int x,int y){
v1[++cnt1].to=y;
v1[cnt1].next=h1[x];
h1[x]=cnt1;
}
int n,m,s,t;
bool vis[N];
void dfs(int x){
vis[x]=1;
for(int i=h1[x];i;i=v1[i].next)
{
int e=v1[i].to;
if(!vis[e]) dfs(e);
}
}
bool use[N],vi1[N];
int f[N];
void df1(int x){
if(!vis[x]||vi1[x]) return ;
vi1[x]=1;
bool flag=1;
for(int i=h[x];i;i=v[i].next)
if(!vis[v[i].to]) return ;
use[x]=1;
if(x==t){
f[x]=0;return ;
}
for(int i=h[x];i;i=v[i].next)
{
df1(v[i].to);
if(use[v[i].to])
f[x]=min(f[x],f[v[i].to]+1);
// if(f[v[i].to]<=5000) printf("%d %d %d %d\n",v[i].to,f[v[i].to],x,f[x]);
}
}
bool vi2[N];
void df2(int x){//与上面完全相同
if(!vis[x]||vi2[x]) return ;
vi2[x]=1;
bool flag=1;
for(int i=h[x];i;i=v[i].next)
if(!vis[v[i].to]) return ;
use[x]=1;
if(x==t){
f[x]=0;return ;
}
for(int i=h[x];i;i=v[i].next)
{
df2(v[i].to);
if(use[v[i].to])
f[x]=min(f[x],f[v[i].to]+1);
// if(f[v[i].to]<=5000) printf("%d %d %d %d\n",v[i].to,f[v[i].to],x,f[x]);
}
}
int main() {
// freopen("in.txt","r",stdin);
n=read();
m=read();
for(int i=1;i<=m;i++)
{
int x=read(),y=read();
add(x,y);dda(y,x);
}
memset(f,127/3,sizeof f);
s=read();
t=read();
// printf("%d %d\n",s,t);
dfs(t);
df1(s);
df2(s);
// for(int i=1;i<=n;i++) printf("%d %d\n",i,f[i]);puts("");
if(use[s]) printf("%d",f[s]);
else puts("-1");
return 0;
}