//Реализацияалгоритма обхода в ширину на примере задачи "Путь". Условие задачи есть в доп. задачах этого дня

#include <cstdio>
const int MAXN=100+10;
const int INF=1<<29;//бесконечность = 2^29

int g[MAXN][MAXN];//матрица смежности графа

int q[MAXN],s,t;//очередь; s - голова, t - хвост (хвост - куда должен встать только что пришедший)
int d[MAXN],from[MAXN];//массивы расстояний и предков вершин в дереве обхода в ширину
int res[MAXN];//вспомогательный массив для вывода ответа

void push(int x){//добавить элемент в конец очереди
    q[t]=x;
    t++;
    if(t==MAXN) t=0;
}
void pop(void){//удалить элемент из начала очереди
    s++;
    if(s==MAXN) s=0;
}

int main(){
    int n,u,v,i,j,st,fn;

    scanf("%d",&n);
    for(i=0;i<n;i++)
        for(j=0;j<n;j++)
            scanf("%d",&g[i][j]);
    scanf("%d%d",&st,&fn);
    st--;fn--;//чтобы нумерация была с нуля

    for(i=0;i<n;i++){
        d[i]=INF;
        from[i]=i;
    }
    d[st]=0;
    push(st);

    while(s!=t){
        u=q[s];
        if(u==fn) break;
        pop();
        for(v=0;v<n;v++)
            if(g[u][v]&&d[v]==INF){
                d[v]=d[u]+1;
                from[v]=u;
                push(v);
            }
    }
    if(d[fn]==INF){//если добраться от st до fn нельзя, вывести -1 и ниего не делать
        printf("-1");
        return 0;
    }

    printf("%d\n",d[fn]);//вывод пути от st до fn
    v=fn;
    for(i=0;from[v]!=v;v=from[v],i++)//идем по массиву предков, пока не наткнемся на стартовую вершину; путь запишем в массив res
        res[i]=v;
    printf("%d ",st+1);//возвращаемся к нумерации с единицы
    //массив res нужно вывести в обратном порядке
    for(i--;i>=0;i--)
        printf("%d ",res[i]+1);
    return 0;
}

Последнее изменение: Суббота, 15 Август 2020, 02:35