原题链接
https://www.luogu.com.cn/problem/P2296
解题思路
读入图时建立正向边和反向边,两次DFS标记所有合法的点,再进行一遍BFS求最短路径。
参考代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80
| #include<cstdio> #include<vector> #include<queue> #include<cstring> #define N 10001 using namespace std; int n,m,t1,t2,s,t,d[N]; bool vis[N],go1[N],go2[N],go[N],inq[N]; vector<int> gt[N],g[N]; queue<int> q; void dfs1(int x) { vis[x]=1; for(int i=0;i<gt[x].size();i++) { int to=gt[x][i]; if(go1[x])go1[to]=1; if(vis[to])continue; dfs1(to); } } void dfs2(int x) { vis[x]=1; for(int i=0;i<g[x].size();i++) { int to=g[x][i]; if(go2[x])go2[to]=1; if(vis[to])continue; dfs2(to); } } int main() { scanf("%d%d",&n,&m); for(int i=1;i<=m;i++) { scanf("%d%d",&t1,&t2); if(t1==t2)continue; gt[t2].push_back(t1); g[t1].push_back(t2); } scanf("%d%d",&s,&t); go1[t]=go2[t]=1; d[t]=-1; dfs1(t); memset(vis,0,sizeof(vis)); dfs2(t); for(int i=1;i<=n;i++) { if(!go1[i]&&!go2[i])continue; go[i]=1; for(int j=0;j<g[i].size();j++) { int to=g[i][j]; if(!go1[to]&&!go2[to]) { go[i]=0; break; } } } q.push(s); inq[s]=1; while(!q.empty()) { int now=q.front(); q.pop(); for(int i=0;i<g[now].size();i++) { int to=g[now][i]; if(inq[to]||!go[to])continue; q.push(to); inq[to]=1; d[to]=d[now]+1; } } printf("%d",d[t]); return 0; }
|