luogu 2296 寻找道路
题目链接:https://www.luogu.org/problemnew/show/P2296
从终点bfs或者dfs,找出所有终点能到达的点.
然后再从1到n看一下出边是否都与终点相连.
然后对于可行的边,做最短路即可.
因为这里的边权是1,所以bfs即可.
CODE:
#include <iostream>
#include <cstdio>
#include <queue>
const int maxN = 20000 + 7;
const int maxM = 400000 + 7;
using namespace std;
struct Node {
int v,nex;
}Map[maxM];
int head[maxN],num;
bool vis[maxN];
void add_Node(int u,int v) {
Map[++ num] = (Node) {v,head[u]};
head[u] = num;
return ;
}
struct Node_2 {
int v,nex;
}Map_2[maxM];
int num_2,head_2[maxN],dep[maxN];
bool vis2[maxN];
void add_Node2(int u,int v) {
Map_2[++ num_2] = (Node_2) {v,head_2[u]};
head_2[u] = num_2;
return ;
}
queue<int> q;
inline int read() {
int x = 0,f = 1;char c = getchar();
while(c < '0' || c > '9') {if(c == '-')f = -1;c = getchar();}
while(c >= '0' && c <= '9') {x = x * 10 + c - '0';c = getchar();}
return x * f;
}
int main() {
int n,m,s,t,u,v;
n = read();m = read();
while(m --) {
u = read();v = read();
add_Node2(u,v);
add_Node(v,u);
}
s = read();t = read();
vis[t] = true;
q.push(t);
while(!q.empty()) {
u = q.front();q.pop();
for(int i = head[u];i;i = Map[i].nex) {
v = Map[i].v;
if(!vis[v]) {
vis[v] = true;
q.push(v);
}
}
}
for(int i = 1;i <= n;++ i) {
if(!vis[i]) vis2[i] = true;
for(int j = head_2[i];j;j = Map_2[j].nex) {
int v = Map_2[j].v;
if(!vis[v]) vis2[i] = true;
}
}
dep[t] = 1;
q.push(t);
while(!q.empty()) {
int p = q.front();q.pop();
for(int i = head[p];i;i = Map[i].nex) {
int v = Map[i].v;
if(!dep[v] && !vis2[v]) {
q.push(v);
dep[v] = dep[p] + 1;
}
}
}
printf("%d",dep[s] == 0 ? -1 : dep[s] - 1);
return 0;
}