这道题嘛。。
首先根据题目,我们要先知道哪些点能够到达终点。(反向BFS)
然后我们再求最短路的途中,必须随时判断周围的点是否被第一次BFS标记过。、
所以再来一次BFS。
数组记得清零,不然会炸。。
下面贴代码
#include<iostream> #include<cstdio> #include<cstring> using namespace std; int n,m,num=0,s,tt; int q[20000]; int step[20000]; int head[10001]; bool vis[10001]; int a[200001],b[200001]; struct edge{ int to,next; }g[400001]; void ins(int u,int v) { g[++num].next=head[u]; head[u]=num; g[num].to=v; } void bfs1(int last){ vis[last]=true; int h=1,t=1; q[h]=last; while(h<=t) { int tmp=q[h]; for(int i=head[tmp];i;i=g[i].next) if(!vis[g[i].to]) { vis[g[i].to]=true; q[++t]=g[i].to; } h++; } } bool chubian(int q){ for(int i=head[q];i;i=g[i].next) if(!vis[g[i].to]) return false; return true; } bool bfs2(int first){ memset(q,0,sizeof(q)); int h=1,t=1; q[h]=first; while(h<=t) { int tmp=q[h++]; if(!chubian(tmp))continue; for(int i=head[tmp];i;i=g[i].next) if(step[g[i].to]==0) { step[g[i].to]=step[tmp]+1; if(g[i].to==tt){printf("%d\n",step[tt]);return true;} q[++t]=g[i].to; } } return false; } int main(){ scanf("%d%d",&n,&m); for(int i=1;i<=m;i++) { scanf("%d%d",&a[i],&b[i]); ins(b[i],a[i]); } scanf("%d%d",&s,&tt); bfs1(tt); memset(head,0,sizeof(head)); memset(g,0,sizeof(g)); num=0; for(int i=1;i<=m;i++) ins(a[i],b[i]); if(!bfs2(s))printf("-1\n"); }
时间: 2024-10-11 07:19:47