Cod sursa(job #1665765)

Utilizator vladrochianVlad Rochian vladrochian Data 27 martie 2016 12:46:56
Problema Santa Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.79 kb
#include <algorithm>
#include <cstdlib>
#include <fstream>
#include <stack>
#include <vector>

using namespace std;

const int N_MAX = 45000;

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

int N, M;
int S, E, Q;

vector<int> G[N_MAX + 5];
bool on_path[N_MAX + 5];
bool use[N_MAX + 5];

int level[N_MAX + 5];
int low[N_MAX + 5];
stack<int> st;

vector<int> art;
vector<vector<int>> bcc;

vector<int> path;

void NoSol() {
   fout << "No chance\n";
   exit(0);
}

void GetComponent(int node, int son) {
   if (!on_path[son]) {
      while (st.top() != son)
         st.pop();
      st.pop();
      return;
   }

   bcc.push_back(vector<int>());
   art.push_back(node);

   while (st.top() != son) {
      bcc.back().push_back(st.top());
      st.pop();
   }
   st.pop();
   bcc.back().push_back(son);
   bcc.back().push_back(node);
}

void Dfs(int node, int padre) {
   use[node] = true;
   level[node] = level[padre] + 1;
   low[node] = level[node];

   for (int i : G[node]) {
      if (i == padre)
         continue;

      if (use[i]) {
         low[node] = min(low[node], level[i]);
      } else {
         st.push(i);
         Dfs(i, node);

         on_path[node] |= on_path[i];
         low[node] = min(low[node], low[i]);

         if (low[i] >= level[node])
            GetComponent(node, i);
      }
   }
}

bool Back(int cnt, int size, int node, int end) {
   use[node] = true;
   if (cnt > 1)
      path.push_back(node);

   if (cnt == size) {
      if (end == 0 || node == end)
         return true;
      use[node] = false;
      path.pop_back();
      return false;
   }

   for (int i : G[node])
      if (!use[i] && (i != end || cnt == size - 1) && Back(cnt + 1, size, i, end))
         return true;

   use[node] = false;
   path.pop_back();
   return false;
}

void SolveBcc(const vector<int> &nodes, int start, int end) {
   for (int i : nodes)
      use[i] = false;

   if (!Back(1, nodes.size(), start, end))
      NoSol();
}

int main() {
   fin >> N >> M;
   while (M--) {
      int x, y;
      fin >> x >> y;
      G[x].push_back(y);
      G[y].push_back(x);
   }
   fin >> S >> E >> Q;

   on_path[S] = true;
   art.assign(1, S);
   bcc.resize(1);

   Dfs(E, 0);
   if (!on_path[E])
      NoSol();

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

   path.push_back(Q);
   for (size_t i = 1; i < bcc.size(); ++i)
      SolveBcc(bcc[i], art[i - 1], art[i]);

   fout << path.size() << "\n";
   for (int i : path)
      fout << i << " ";
   fout << "\n";
   return 0;
}