Cod sursa(job #2060405)

Utilizator lulian23Tiganescu Iulian lulian23 Data 8 noiembrie 2017 10:48:34
Problema Santa Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.91 kb
#include <bits/stdc++.h>
#define nmax 45000 + 1
#define nuu cout << "No chance";

using namespace std;

FILE*f = freopen("santa.in", "r", stdin);
FILE*g = freopen("santa.out", "w", stdout);

int n, m, S, D, Q;

vector < int > v[ nmax ];
vector < int > art;
vector < vector < int > > bcc;

int st[ nmax ], disc[ nmax ], low[ nmax ];

bitset < nmax > used[ nmax ];
bitset < nmax > inst[ nmax ];
bitset < nmax > drum[ nmax ];

vector < int > path;

void Bc(int nod, int son)
{
    if (drum[ son ] == 0){
        while (st[ 0 ] > 0 && st[st[ 0 ]] != son)

            inst[st[st[ 0 ] --]] = 0;

        inst[st[st[ 0 ] --]] = 0;
        return ;
    }
    else{
        bcc.push_back(vector<int>());
        art.push_back(nod);
        while (st[0] > 0 && st[st[0]] != son){
            inst[st[st[0]]] = 0;
            bcc.back().push_back(st[st[0] --]);
        }
        bcc.back().push_back(st[st[0] --]);
        inst[son] = 0;
        bcc.back().push_back(nod);
    }
}

void dfs(int u, int p){
    disc[ u ] = low[ u ] = disc[ p ] + 1;
    inst[ u ] = 1;
    st[++ st[ 0 ]] = u;
    for (int V : v[ u ])
        if (!disc[ V ]){
            dfs(V, u);
            drum[ u ] |= drum[ V ];
            low[ u ] = min(low[ u ], low[ V ]);
            if (low[ V ] >= disc[ u ])
                Bc(u, V);
        }
        else if (V != p && inst[ V ] == 1)
            low[ u ] = min(low[ u ], disc[ V ]);
}


bool Back(int cnt, int sz, int x, int en)
{
    used[ x ] = true;
    if (cnt != 1)
        path.push_back( x );

    if (cnt == sz){
        if (en == 0 || x == en)
            return true;
        used[ x ] = false;
        path.pop_back();
        return false;
    }

    for (int y : v[ x ])
        if (used[ y ] == 0 && (y != en || cnt == sz - 1) && Back(cnt + 1, sz, y, en))
            return true;
    used[ x ] = false;
    path.pop_back();
    return false;
}

int main()
{
    scanf("%d %d", &n, &m);

    for (int i = 1, x, y; i <= m; ++ i){
        scanf("%d %d", &x, &y);

        v[ x ].push_back( y );
        v[ y ].push_back( x );
    }

    scanf("%d %d %d", &S, &D, &Q);
    art.push_back( S );
    drum[ S ] = 1;
    dfs(D, 0);

    if (find(bcc[0].begin(), bcc[0].end(), Q) == bcc[0].end()){
        reverse(bcc.begin(), bcc.end());
        reverse(art.begin(), art.end());
    }

    if (drum[ D ] == 0 || find(bcc[0].begin(), bcc[0].end(), Q) == bcc[0].end()){
        nuu;
        return 0;
    }

    art[ 0 ] = Q;
    art.back() = 0;
    path.push_back( Q );

    memset(used, 1, sizeof(used));
    for (int i = 0; i < bcc.size(); ++ i){
        for (int j : bcc[i])
            used[ j ] = 0;
        if (!Back(1, bcc[i].size(), art[i], art[i + 1])){
            nuu;
            return 0;
        }
    }

    printf("%d\n", path.size());
    for (int i : path)
        printf("%d ", i);
    return 0;
}