题意
有向图最短路,有条件:路上每个节点能 直接 到达的节点,要与终点直接或间接相连
题解
bfs预处理能用的点,然后SPFA
调试记录
注意是直接,所以要先记录到另一个数组里
#include <cstdio>
#include <queue>
#include <cstring>
#define maxn 10005
using namespace std;
struct node{
int to, next;
}opp[200005], e[200005];
int n, m, s, t, tot1 = 0, tot2 = 0, head_opp[200005], head_e[200005];
int dis[maxn];
bool avb[maxn];
void addedge(int u, int v){
opp[++tot1] = (node){u, head_opp[v]};
head_opp[v] = tot1;
e[++tot2] = (node){v, head_e[u]};
head_e[u] = tot2;
}
void bfs(int start){
queue <int> q; while (!q.empty()) q.pop();
q.push(start);
while (!q.empty()){
int now = q.front(); q.pop();
if (avb[now]) continue;
avb[now] = true;
for (int i = head_opp[now]; i; i = opp[i].next){
if (!avb[opp[i].to]) q.push(opp[i].to);
}
}
bool arr[maxn];
memset(arr, true, sizeof arr);
for (int i = 1; i <= n; i++)
if (!avb[i]){
for (int j = head_opp[i]; j; j = opp[j].next)
arr[opp[j].to] = false;
}
for (int i = 1; i <= n; i++)
if (!arr[i]) avb[i] = false;
}
bool vis[maxn];
void SPFA(int start){
memset(dis, 0x3f, sizeof dis);
dis[start] = 0;
queue <int> q; while (!q.empty()) q.pop();
q.push(start);
while (!q.empty()){
int now = q.front(); q.pop();
vis[now] = true;
for (int i = head_e[now]; i; i = e[i].next){
if (dis[e[i].to] > dis[now] + 1 && avb[e[i].to]){
if (!vis[e[i].to]) q.push(e[i].to);
dis[e[i].to] = min(dis[e[i].to], dis[now] + 1);
}
}
}
}
int main(){
scanf("%d%d", &n, &m);
for (int x, y, z, i = 1; i <= m; i++){
scanf("%d%d", &x, &y);
addedge(x, y);
}
scanf("%d%d", &s, &t);
bfs(t);
if (!avb[s]){
printf("-1");
return 0;
}
SPFA(s);
printf("%d\n", dis[t]);
return 0;
}