[题解] P2296 寻找道路 DFS/BFS 最短路
洛谷题目链接
牛客题目链接
题目要求路径上的所有点的出边所指向的点都直接或间接与终点连通,我们可以先做一遍dfs找出那些点与终点联通,再依次判断每一个点所有出边所连节点是否有和终点不联通的,如果有那么这个节点不满足条件
声明:c[i]表示节点i是否与终点联通,_c[i]表示节点i是否可以经过 (限于水平,数组的名字不太优美,是can的简写)
求数组c的代码:
void dfs(int u){
c[u]=1;
for(int v=0;v<_to[u].size();v++)if(!c[_to[u][v]])dfs(_to[u][v]);
}
求数组_c的代码:
for(int i=1;i<=n;i++){
_c[i]=1;
for(int j=0;j<to[i].size();j++)if(!c[to[i][j]])_c[i]=0;
//printf("%d ",_c[i]);
}
时间复杂度最差时为O(m)
得到了_c数组之后,就是最短路的过程,可以用bfs解决,这样本题就既练习了bfs又练习了dfs,当然两个过程用bfs还是dfs都可以解决
void bfs(){
for(int i=1;i<=n;i++)dis[i]=1e9+7;
q.push(s),dis[s]=0,vis[s]=1;
while(!q.empty()){
int u=q.front();
q.pop();
for(int v=0;v<to[u].size();v++)if(_c[to[u][v]]&&!vis[to[u][v]]){
dis[to[u][v]]=dis[u]+1;
vis[to[u][v]]=1;
q.push(to[u][v]);
}
}
}
最后判断一下,如果dis[t]=1e9+7,那么代表这样的路径不存在,输出-1
AC代码:
#include <cstdio>
#include <vector>
#include <queue>
using namespace std;
const int maxn=1e4+7;
int n,m,s,t;
int c[maxn],_c[maxn],dis[maxn],vis[maxn];
vector<int> to[maxn],_to[maxn];
queue<int> q;
void dfs(int u){
c[u]=1;
for(int v=0;v<_to[u].size();v++)if(!c[_to[u][v]])dfs(_to[u][v]);
}
void bfs(){
for(int i=1;i<=n;i++)dis[i]=1e9+7;
q.push(s),dis[s]=0,vis[s]=1;
while(!q.empty()){
int u=q.front();
q.pop();
for(int v=0;v<to[u].size();v++)if(_c[to[u][v]]&&!vis[to[u][v]]){
dis[to[u][v]]=dis[u]+1;
vis[to[u][v]]=1;
q.push(to[u][v]);
}
}
}
int main(){
scanf("%d%d",&n,&m);
for(int i=1;i<=m;i++){
int u,v;
scanf("%d%d",&u,&v);
to[u].push_back(v);
_to[v].push_back(u);
}
scanf("%d%d",&s,&t);
dfs(t);
for(int i=1;i<=n;i++){
_c[i]=1;
for(int j=0;j<to[i].size();j++)if(!c[to[i][j]])_c[i]=0;
//printf("%d ",_c[i]);
}
bfs();
if(dis[t]==1e9+7)dis[t]=-1;
printf("%d",dis[t]);
return 0;
}
希望本篇文章可以帮助到大家