Cod sursa(job #3326938)

Utilizator stefan_dore_Stefan Dore stefan_dore_ Data 1 decembrie 2025 15:09:53
Problema Santa Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 3.48 kb
#include <iostream>
#include <fstream>
#include <vector>
#include <stack>
#include <algorithm>
using namespace std;

ifstream f ("santa.in");
ofstream g ("santa.out");

const int NMAX = 45000;
int N, M, s, e, q, Rad, Niv[NMAX+1], Nma[NMAX+1], nrCB, PA[NMAX+1];
bool viz[NMAX+1], inDrum[NMAX+1];

vector<int> G[NMAX+1], CB[NMAX+1], Drum;
stack<int> S;

void citire() {
    f >> N >> M;
    //
    int x, y;
    for (int i=1; i<=M; i++) {
        f >> x >> y;
        G[x].push_back(y);
        G[y].push_back(x);
    }
    //
    f >> s >> e >> q;
}

void DFS(int nod, int tata) {
    S.push(nod);
    viz[nod] = 1;
    Niv[nod] = Niv[tata] + 1;
    Nma[nod] = Niv[nod];
    //
    for(const auto &x : G[nod]) {
        if(x == tata) continue;
        //
        if(viz[x]) Nma[nod] = min(Nma[nod], Niv[x]);
        else {
            DFS(x, nod);
            inDrum[nod] |= inDrum[x];
            Nma[nod] = min(Nma[nod], Nma[x]);
            //
            if(Niv[nod] <= Nma[x]) {
                if (!inDrum[x]) {
                    while(S.top() != x)
                        S.pop();
                    S.pop();
                } else {
                    ++nrCB;
                    while(S.top() != x) {
                        CB[nrCB].push_back(S.top());
                        S.pop();
                    }
                    CB[nrCB].push_back(x);
                    S.pop();
                    CB[nrCB].push_back(nod);

                    PA[nrCB] = nod;
                }
            }
        }
    }
}

bool findNod(int nod, int cb) {
    for (const auto &x : CB[cb])
        if(x == nod)
            return 1;
    return 0;
}

bool Backtracking(int k, int n, int nod, int fin) {
    if (k == n) {
        for (const auto &x : G[nod])
            if (!viz[x])
                if (x == fin || fin == -1) {
                    viz[x] = 1;
                    Drum.push_back(x);
                    return 1;
                }
    } else {
        for (const auto &x : G[nod]) {
            if (!viz[x]) {
                if (x == fin) continue;
                //
                Drum.push_back(x);
                viz[x] = 1;
                //
                bool vizTot = Backtracking(k+1, n, x, fin);
                if (vizTot) return 1;
                //
                Drum.pop_back();
                viz[x] = 0;
            }
        }
    }
    return 0;
}

int main(){
    citire();
    //
    Rad = s;
    inDrum[e] = 1;
    DFS(Rad, 0);
    //
    if (!findNod(q, 1) && !findNod(q, nrCB))
        g << "No chance";
    else {
        if(findNod(q, nrCB)) {
            reverse(CB+1, CB+nrCB+1);
            reverse(PA+1, PA+nrCB+1);
        } else
            for (int i=nrCB-1; i>=1; i--)
                PA[i+1] = PA[i];
        //
        for (int i=1; i<=N; i++)
            viz[i] = 1;
        PA[1] = q; PA[nrCB+1] = -1;
        Drum.push_back(q);
        //
        for (int i=1; i<=nrCB; i++) {
            for (const auto &x : CB[i])
                viz[x] = 0;
            //
            viz[PA[i]] = 1;
            bool vizTot = Backtracking(2, CB[i].size(), PA[i], PA[i+1]);
            //
            if (!vizTot) {
                g << "No chance";
                return 0;
            }
        }
        //
        g << Drum.size() << '\n';
        for(const auto &x : Drum)
            g << x << ' ';
    }
    //
    f.close();
    g.close();
    return 0;
}