最短路——洛谷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]);
}
posted @ 2017-04-17 13:56  largecube233  阅读(128)  评论(0编辑  收藏  举报