Cod sursa(job #2972534)

Utilizator andrei_marciucMarciuc Andrei andrei_marciuc Data 29 ianuarie 2023 17:56:12
Problema Santa Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 3.26 kb
#include <algorithm>
#include <iostream>
#include <fstream>
#include <vector>
#include <stack>
using namespace std;

ifstream fin( "santa.in" );
ofstream fout( "santa.out" );

const int MAX = 45002;
vector<int> G[ MAX ];

int n, m, S, E, Q;
int level[ MAX ];
int lL[ MAX ];
bool ok[ MAX ];
stack<int> stiva;

vector<vector<int>> comp;
vector<int> critic;

void findBiconex( int nod, int parent ) {
    lL[ nod ] = level[ nod ] = level[ parent ] + 1;
    stiva.push( nod );

    ok[ nod ] = ( nod == E ? true : ok[ nod ] );
    for( auto vec : G[ nod ] )
        if( vec != parent ) {
            if( level[ vec ] != 0 )
                lL[ nod ] = min( lL[ nod ], level[ vec ] );
            else {
                findBiconex( vec, nod );
                ok[ nod ] = ( ok[ vec ] == true ? ok[ vec ] : ok[ nod ] );
                lL[ nod ] = min( lL[ nod ], lL[ vec ] );
                if( level[ nod ] <= lL[ vec ] ) {
                    vector<int> aux;
                    while( stiva.top() != vec ) {
                        aux.push_back( stiva.top() );
                        stiva.pop();
                    }
                    aux.push_back( vec );
                    stiva.pop();
                    aux.push_back( nod );

                    if( ok[ vec ] ) {
                        comp.push_back( aux );
                        critic.push_back( nod );
                    }
                }
            }
        }
}

vector<int> rez;
bool interest[ MAX ];
bool Find( int start, int end, int size, bool status ) {
    interest[ start ] = false;
    if( status )
        rez.push_back( start );
    
    if( size == 1 )
        if( start == end || end == 0 )
            return true;

    if( size == 1 || start == end ) {
        interest[ start ] = true;
        if( status )
            rez.pop_back();
        return false;
    }

    for( auto vec : G[ start ] )
        if( interest[ vec ] && Find( vec, end, size - 1, 1 ) )
            return true;

    if( status )
        rez.pop_back();
    interest[ start ] = true;
    return false;
}

int main()
{
    fin >> n >> m;
    for( int i = 1; i <= m; i++){
        int a, b;
        fin >> a >> b;
        G[ a ].push_back( b );
        G[ b ].push_back( a );
    }

    fin >> S >> E >> Q;

    critic.push_back( Q );
    findBiconex( S, 0 );

    bool normal = false;
    for( auto nod : comp[ 0 ] )
        normal |= (nod == Q);

    if( !normal ) {
        reverse( comp.begin(), comp.end() );
        reverse( critic.begin(), critic.end() );
    }

    normal = false;
    for( auto nod : comp[ 0 ] )
        normal |= (nod == Q);

    if( !normal ) {
        fout << "No chance\n";
        return 0;
    }

    critic[ 0 ] = Q;
    critic[ (int)critic.size() - 1 ] = 0;
    for( auto C : comp)
        for( auto nod : C )
            interest[ nod ] = true;

    for( int i = 0; i < (int)comp.size(); i++ ) {
        interest[ critic[ i ] ] = true;
        if( !Find( critic[ i ], critic[ i + 1 ], (int)comp[ i ].size(), 1 ) ) {
            fout << "No chance\n";
            return 0;
        }

        if( i != (int)comp.size() - 1 )
            rez.pop_back();

        for( auto nod : comp[ i ] )
            interest[ nod ] = false;
    }

    fout << (int)rez.size() << '\n';
    for( auto nod : rez )
        fout << nod << ' ';
    return 0;
}