Description
一张有向图 长度均为1 输入格式为x y 表示x和y之间有一条路
给定s和t 求s到t的最短路
要求:
路径上的所有点的出边所指向的点都直接或间接与终点连通
Solution
在这里点包括3种:
1 自己指向的节点都可以到达终点
2 自己可以到达终点的点
3 普通的点
显然 3包括2 2包括1 这里要的是由1组成的最短路
我们可以建立反向路 从t点bfs 标记能到达的点 这里的点为2
枚举所有没被标记的点 他们可以到达的点如果为2 则取消标记
这样被标记的点就是1了 我们就可以开开心心的跑bfs求最短路了
Code
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
![](https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif)
1 #include <iostream> 2 #include <cstdio> 3 #include <queue> 4 #include <vector> 5 #include <cstring> 6 #include <cstdlib> 7 using namespace std; 8 int n, m, s, t; 9 int pre[10010], ans[100010]; 10 bool f[10010], ff[10010]; 11 vector<int>v[10010]; 12 queue<int>q; 13 int main(){ 14 ios::sync_with_stdio(false); 15 cin >> n >> m; 16 for (int i = 1;i <= m; i++) { 17 int a, b; 18 cin >> a >> b; 19 if (a == b) continue; 20 v[b].push_back(a); 21 } 22 cin >> s >> t; 23 q.push(t); 24 f[t] = 1; 25 while (!q.empty()) { 26 int now = q.front(); 27 q.pop(); 28 int len = v[now].size(); 29 for (int i = 0;i < len; i++) 30 if (!f[v[now][i]]) { 31 f[v[now][i]] = 1; 32 q.push(v[now][i]); 33 } 34 } 35 memcpy(ff, f, sizeof(f)); 36 for (int i = 1;i <= n; i++) 37 if (!f[i]) 38 for (int j = 0, k = v[i].size();j < k; j++) 39 if (ff[v[i][j]]) 40 ff[v[i][j]] = 0; 41 q.push(t); 42 ans[s] = -1; 43 while (!q.empty()) { 44 int now = q.front(); 45 q.pop(); 46 for (int i = 0, j = v[now].size();i < j; i++) 47 if (ff[v[now][i]]) { 48 q.push(v[now][i]); 49 ff[v[now][i]] = 0; 50 ans[v[now][i]] = ans[now] + 1; 51 } 52 } 53 cout << ans[s] << endl; 54 return 0; 55 }