最短路——洛谷P2296 寻找道路
https://www.luogu.org/problem/show?pid=2296
先建反图,从终点开始跑bfs,得出所有可以到终点的点;
然后在正图里面跑最短路就好了;
堆优化和spfa都有;
#include <iostream>
#include <string>
#include <cstdio>
#include <cstring>
#include<algorithm>
#include<queue>;
#define Ll long long
using namespace std;
struct cs{
int to,nxt;
}a[2000005];
struct KK{
int v,num; //这↓个const不加也AC
bool operator <( const KK a)const{
return v>a.v;
}
};
int head[10005],ll;
int IN[2000005][2];
bool ok[10005],vi[10005];
int q[100005],l,r;
int d[10005];
int n,m,x,y,z,S,E;
void init(int x,int y){
a[++ll].to=y;
a[ll].nxt=head[x];
head[x]=ll;
}
void bfs(int S){
q[1]=S;
r=1;ok[S]=1;
while(r>l){
int x=q[++l];
for(int k=head[x];k;k=a[k].nxt)
if(!ok[a[k].to]){
q[++r]=a[k].to;
ok[a[k].to]=1;
}
}
}
void dijstar(int S){
priority_queue<KK>Q;
KK x;
for(int i=1;i<=n;i++){
d[i]=1e9;
Q.push(KK{1e9,i});
}
d[S]=0;
Q.push(KK{0,S});
while(1){
int mi=0;
while(!Q.empty()){
x=Q.top();Q.pop();
if(!vi[x.num])break;
}
if(Q.empty())return;
vi[mi=x.num]=1;
for(int k=head[mi];k;k=a[k].nxt)
if(d[a[k].to]>d[mi]+1){
d[a[k].to]=d[mi]+1;
Q.push(KK{d[mi]+1,a[k].to});
}
}
}
void spfa(int S){
queue<int>Q;
for(int i=1;i<=n;i++)d[i]=1e9;
d[S]=0;vi[S]=1;
Q.push(S);
while(!Q.empty()){
int mi=Q.front();
Q.pop();
vi[mi]=0;
for(int k=head[mi];k;k=a[k].nxt)
if(d[a[k].to]>d[mi]+1){
d[a[k].to]=d[mi]+1;
if(!vi[a[k].to]){
vi[a[k].to]=1;
Q.push(a[k].to);
}
}
}
}
int main()
{
scanf("%d%d",&n,&m);
for(int i=1;i<=m;i++){
scanf("%d%d",&x,&y);
IN[i][0]=x;
IN[i][1]=y;
if(x==y)continue;
init(y,x);
}scanf("%d%d",&S,&E);
bfs(E);
memset(head,0,sizeof head);ll=0;
for(int i=1;i<=m;i++){
x=IN[i][0];
y=IN[i][1];
if(x==y)continue;
init(x,y);
}
for(int i=1;i<=n;i++)
for(int k=head[i];k;k=a[k].nxt)
if(!ok[a[k].to])vi[i]=1;
dijstar(S);
// spfa(S);
if(d[E]==1e9)printf("-1");else printf("%d",d[E]);
}