最短路——洛谷P2296 寻找道路

来源:互联网 发布:王者荣耀 英雄成长数据 编辑:程序博客网 时间:2024/05/22 01:46

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]);}
1 0
原创粉丝点击