首先我们可以作为路径中的点的节点一定会满足它的子节点全部和终点连通
那么就要找出所有能和终点连通的点
考虑反向建边,从终点开始遍历,将能与它连通的点打上标记
再暴力枚举每一个点,如果它出边所连接的点中有不和终点连接的点就删除这个点
再对剩余的点到终点求一个最短路就可以
由于所有边边权都是1直接用bfs就可以求出最短路
(但我是憨憨所以没用)
#include<iostream>
#include<cstdio>
#include<vector>
#include<queue>
#include<string>
#include<cstring>
using namespace std;
int read(){
int a = 0,f = 0;char p = getchar();
while(!isdigit(p)){f|=p=='-';p = getchar();}
while(isdigit(p)){a=(a<<3) + (a<<1) +(p^48);p = getchar();}
return f?-a:a;
}
vector<int> mmp[10001];
vector<int> f[10001];
int n,m,s,t;
queue<int> q;
bool flag[20000];//?ж???????
bool del[20000];//????????
bool vis[20000];
priority_queue<pair<int,int> > qwq;
int dis[20000];
void bfs(int x){
q.push(x);
flag[x] = 1;
while(!q.empty()){
int u = q.front();
//cout<<u<<endl;
for(int i = 0;i < f[u].size();i++){
if(!flag[f[u][i]]){
flag[f[u][i]] = 1;
q.push(f[u][i]);
}
}
q.pop();
}
}
void delet(){
for(int i = 1;i <= n;i ++){
for(int j = 0;j < mmp[i].size();j++){
int v = mmp[i][j];
if(flag[v] == 0){
//cout<<v<<" "<<i<<endl;
del[i] = 1;}
}
}
}
void _short(){
//cout<<"FUCKKKK";
int x,y;
memset(dis,1061109567,sizeof(dis));
dis[s] = 0;
qwq.push(make_pair(0,s));//答案 编号
while(!qwq.empty()){
x = qwq.top().second;
qwq.pop();
if(vis[x])continue;
vis[x] = 1;
for(int i = 0;i < mmp[x].size();i++){
y = mmp[x][i];
if(del[y])continue;
if(dis[y] > dis[x] + 1){
dis[y] = dis[x] + 1;
qwq.push(make_pair(-dis[x]-1,y));
}
}
}
//for(int i = 1; i<= n; i++)cout<<dis[i]<<endl;
if(dis[t] >= 1061109567)cout<<-1<<endl;
else cout<<dis[t]<<endl;
}
int main(){
//cout<<0x3f<<endl;
n = read();m = read();
int x,y;
for(int i = 1;i <= m;i++){
x = read();y = read();
if(x == y)continue;
mmp[x].push_back(y);//??x??y???????
f[y].push_back(x);//??????
}
s = read();t = read();
bfs(t);
if(flag[s] == 0){cout<<"-1";return 0;}
delet();
if(del[s] == 1){cout<<"-1";return 0;}
_short();
}