Cod sursa(job #2090875)

Utilizator borcanirobertBorcani Robert borcanirobert Data 18 decembrie 2017 20:02:27
Problema Santa Scor 20
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.78 kb
#include <iostream>
#include <algorithm>
#include <fstream>
#include <vector>
#include <stack>
using namespace std;

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

const int MAX = 45005;
vector<vector<int>> G, comp; // comp = componentele biconexe
int N, M, Start, Finish, First;
vector<int> low, h, good;
vector<int> a;  // punctele de articulatie
stack<int> st;
bool sol{true};
vector<int> path, canGo;
//int l[MAX];

void Read();
void DFS(int node, int f);
bool FindPath(int node, int target, int r, bool ok);
vector<int> NewComponent(int node);

int main()
{
    Read();

    a.push_back(0);
    DFS(Start, 0);

  //  for (int& x : a)
      //  cout << x << ' ';

    bool g = false;
    for (const int& x : comp[0])
        if (x == First)
        {
            g = true;
            break;
        }

    if (!g)
    {
        reverse(comp.begin(), comp.end());
        reverse(a.begin(), a.end());
    }
    g = false;
    for (const int& x : comp[0])
        if (x == First)
        {
            g = true;
            break;
        }

    if (!g)
        sol = false;
    a.front() = First;
    a.back() = 0;

    for (auto& v : comp)
        for (int& x : v)
            canGo[x] = true;

    path.push_back(First);
    for (size_t i = 0; i < comp.size() && sol; ++i)
    {
        if (!FindPath(a[i], a[i + 1], comp[i].size(), 0))
        {
            sol = false;
            break;
        }

     //   if (i + 1 < comp.size())
      //      path.pop_back();

        for (const int& x : comp[i])
            canGo[x] = false;
    }

    if (!sol)
        fout << "No chance" << '\n';
    else
    {
        fout << path.size() << '\n';
        for (size_t i = 0; i < path.size(); ++i)
        {
        /*    if (l[path[i]])
                while (true)
                    ++i;
            l[path[i]] = true;  */

            fout << path[i] << ' ';
        }
    }

   /* for (const auto& v : comp)
    {
        fout << "Componenta contine " << v.size() << " elemente: ";
        for (const int& x : v)
            fout << x << ' ';
        fout << '\n';
    }   */

    fin.close();
    fout.close();
    return 0;
}

void Read()
{
    fin >> N >> M;

    int x, y;
    G = vector<vector<int>>(N + 1);
    canGo = good = low = h = vector<int>(N + 1);
    while (M--)
    {
        fin >> x >> y;

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

    fin >> Start >> Finish >> First;
}

void DFS(int node, int f)
{
    low[node] = h[node] = h[f] + 1;
    st.push(node);

    if (node == Finish)
        good[node] = true;

    for (int& next : G[node])
    {
        if (next == f)
            continue;

        if (h[next])
        {
            low[node] = min(low[node], h[next]);
            continue;
        }

        DFS(next, node);
        good[node] |= good[next];
        low[node] = min(low[node], low[next]);

        if (h[node] <= low[next])
        {
            vector<int> C = NewComponent(node);

            if (!good[next])
                continue;

            comp.push_back(C);
            a.push_back(node);
        }
    }
}

vector<int> NewComponent(int node)
{
    vector<int> comp;

    while (st.top() != node)
    {
        comp.push_back(st.top());
        st.pop();
    }
    comp.push_back(node);

    return comp;
}

bool FindPath(int node, int target, int r, bool ok)
{
    if (ok)
        path.push_back(node);
    canGo[node] = false;

    if (r == 1 && (node == target || target == 0))
    {
        return true;
    }
    if (node == target || r == 1)
    {
        canGo[node] = true;
        if (ok)
            path.pop_back();

        return false;
    }

    for (const int& next : G[node])
        if (canGo[next] && FindPath(next, target, r - 1, 1))
        {
            return true;
        }

    if (ok)
        path.pop_back();
    canGo[node] = true;
    return false;
}