题目
题解
–这道题就是暴力搜索路径,但是因为有先决条件,所以说要用一种高效又简单的方法找到不能与终点相连的节点
那就是:反向建图
我们只需要从终点开始找,能到的,和不能到的,一下就分清了
找出来后,我们再找路径是就能把它们和能走到它们的最近的父节点都排除在外(因为路径上所有的节点所指向的点都直接或间接的与终点相连)
–不过我第一次做的时候,用的是dfs,就找不到路径,是因为有些情况dfs不能找全(如Y字形的三个节点),又不好处理环和重路,所以改为bfs就AC啦
代码
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<vector>
using namespace std;
const int MAXN=1e4+5;
int n,m;
vector<int>G[MAXN];
bool can[MAXN],isv[MAXN];
int s,t;
int ans=0x3f3f3f3f;
bool flag;
int H,T,p[200005][2];
void no(int x){
for(int i=0;i<G[x].size();i++){
int u=G[x][i];
if(!can[u]){
can[u]=1;
no(u);
}
}
}
void bfs(){
int u=p[H][0];
if(u==s){
flag=1;
ans=min(ans,p[H][1]);
return ;
}
for(int i=0;i<G[u].size();i++){
int v=G[u][i];
if(!isv[v]){
T++;
p[T][0]=v;
p[T][1]=p[H][1]+1;
isv[v]=1;
}
}
if(T>H){
H++;
bfs();
}
}
int main(){
// freopen("road.in","r",stdin);
// freopen("road.out","w",stdout);
cin>>n>>m;
for(int i=1;i<=m;i++){
int u,v;
scanf("%d%d",&u,&v);
G[v].push_back(u);
}
cin>>s>>t;
can[t]=1;
no(t);
for(int i=1;i<=n;i++){
if(!can[i]){
isv[i]=1;
for(int j=0;j<G[i].size();j++){
int u=G[i][j];
isv[u]=1;
}
}
}
H=1;
T=1;
p[H][0]=t;
p[H][1]=0;
bfs();
if(flag)
cout<<ans;
else
cout<<-1;
return 0;
}