题解 P2296 【寻找道路】
yangyujia18 · · 题解
所有边边权一样,所以我们用bfs就能求(何况本蒟蒻觉得dij很难写)
首先,这里有的点不能走,那么我们只要把这些点去掉即可
怎么去掉呢?总不能把每一个点都跑一遍bfs吧......
反着从终点开始跑,只需要反向建图,不仅可以省去大量时间,而且因为数据比较小,不会炸
反向跑之后标出所有可以走的点,再正向跑一次即可
#include<bits/stdc++.h>
using namespace std;
int n,m,start,end;
bool lian[10000],cu[10000];
vector<int> path[10000],fanpath[10000];
struct qu
{
int ni,w;
};
int main()
{
cin>>n>>m;
for(int i=1;i<=m;i++)
{
int st,ed;
cin>>st>>ed;
path[st].push_back(ed);
fanpath[ed].push_back(st);
}
cin>>start>>end;
memset(lian,false,sizeof(lian));
memset(cu,true,sizeof(cu));
//反向
queue<int> q1;
q1.push(end);
while(!q1.empty())
{
int now=q1.front();
q1.pop();
lian[now]=true;
for(int i=0;i<fanpath[now].size();i++)
q1.push(fanpath[now][i]);
}
if(!lian[start])
{
cout<<-1<<endl;
return 0;
}
//处理
for(int i=1;i<=n;i++)
for(int j=0;j<path[i].size();j++)
if(!lian[i]||!lian[path[i][j]])
cu[i]=false;
//正向
queue<qu> q2;
q2.push(qu{start,0});
while(!q2.empty())
{
int now=q2.front().ni,wei=q2.front().w;
q2.pop();
if(now==end)
{
cout<<wei<<endl;
return 0;
}
for(int i=0;i<path[now].size();i++)
if(cu[path[now][i]])
q2.push(qu{path[now][i],wei+1});
}
}
蒟蒻坚持己见觉得这是最简单的方法并且不接受反驳