思路:
以图论方法完成。存图时在正向图g上存储,再将边反过来在gr上存储。目的是,反向图上终点能到的点都是正向图上能到终点的点。然后在反向图上从终点出发BFS或DFS,标记能到终点的点。在正向图从起点开始时,进行BFS时先遍历i结点指向的每个j,如果有任意一个j没有被标记,则i不可以走,直接再从队列中取一个i验证。
代码:
#include<cstdio>
#include<cstring>
#include<vector>
#include<algorithm>
#include<queue>
#define maxn 10005
using namespace std;
int n,m,s,t;
vector<int>g[maxn],gr[maxn];
int d[maxn];
void init()
{
scanf("%d%d",&n,&m);
int x,y;
for(int i=1;i<=m;i++)
{
scanf("%d%d",&x,&y);
g[x].push_back(y);
gr[y].push_back(x);
}
scanf("%d%d",&s,&t);
}
bool inq[maxn],vis[maxn];;
void BFS(int s,int *d)
{
queue<int>q;
memset(d,0,sizeof(d));
q.push(s);
inq[s]=1;
d[s]=0;
while(!q.empty())
{
int i=q.front(); q.pop();
bool ok=1;
for(int k=0;k<g[i].size();k++)
{
if(vis[g[i][k]]==0) ok=0;
}
if(ok==0) continue;
for(int k=0;k<g[i].size();k++)
{
int j=g[i][k];
if(inq[j]) continue;
q.push(j);
inq[j]=1;
d[j]=d[i]+1;
}
}
}
void DFS1(int i)
{
vis[i]=1;
for(int k=0;k<gr[i].size();k++)
{
int j=gr[i][k];
if(vis[j]) continue;
DFS1(j);
}
}
void solve()
{
DFS1(t);
memset(d,0,sizeof(d));
BFS(s,d);
if(d[t]==0) printf("-1\n");
else printf("%d\n",d[t]);
}
int main()
{
//freopen("in.txt","r",stdin);
init();
solve();
return 0;
}