Cod sursa(job #1760584)

Utilizator depevladVlad Dumitru-Popescu depevlad Data 20 septembrie 2016 23:52:02
Problema Santa Scor 60
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.85 kb
#include <bits/stdc++.h>

using namespace std;

const int kMaxN = 45005;
  
int n, m, size, s, t, q;
int dfu[kMaxN];
int depth[kMaxN];
bool insideComp[kMaxN];
vector <int> graph[kMaxN];
vector <int> path;
vector <int> comp;
vector <int> crpath;
stack <pair <int, int>> dfsStack;

bool Back(const int i, const int u, const int f, bool &updated) {
  bool hasCycle = false;
  if (i < size && insideComp[f]) {
    for (const int v: graph[u]) {
      if (insideComp[v] && (i == size - 1 || v != f)) {
        insideComp[v] = false;
        crpath.push_back(v);
        hasCycle |= Back(i + 1, v, f, updated);
        crpath.pop_back();
        insideComp[v] = true;
      }
    }
  }
  else if (i == size) {
    if (!updated) {
      updated = true;
      path.insert(path.end(), crpath.begin(), crpath.end());
    }
    hasCycle = true;
  }
  return hasCycle;
}

bool dfsBiconnected(const int u, const int s, const int t, bool &gotPath) {
  bool goodPath = (u == t);
  dfu[u] = depth[u];
  for (const int v: graph[u]) {
    if (u == q || depth[v] != depth[u] - 1) {
      if (!depth[v]) {
        depth[v] = depth[u] + 1;
        dfsStack.push(make_pair(u, v));
        bool goodNext = dfsBiconnected(v, s, t, gotPath);
        dfu[u] = min(dfu[u], dfu[v]);
        if (depth[u] <= dfu[v]) {
          comp = {u, v};
          while (!dfsStack.empty() && dfsStack.top() != make_pair(u, v)) {
            comp.push_back(dfsStack.top().second);
            dfsStack.pop();
          }
          dfsStack.pop();
          size = comp.size();
          if (goodNext) {
            for (const int node: comp) {
              insideComp[node] = true;
            }
            insideComp[path.back()] = false;
            gotPath &= (u != q || insideComp[s]);
            bool updated = false;
            gotPath &= Back(1, path.back(), u, updated);
            for (const int node: comp) {
              insideComp[node] = false;
            }
          }
        }
        goodPath |= goodNext;
      }
      else {
        dfu[u] = min(dfu[u], depth[v]);
      }
    }
  }
  return goodPath;
}

bool trySolution(const int s, const int t) {
  bool isSolution = true;
  path = { t };
  dfsBiconnected(q, s, t, isSolution);
  return isSolution;
}

int main() {
  freopen("santa.in", "r", stdin);
  freopen("santa.out", "w", stdout);
  
  scanf("%d %d", &n, &m);
  for (int i = 1; i <= m; i++) {
    int u, v;
    scanf("%d %d", &u, &v);
    graph[u].push_back(v);
    graph[v].push_back(u);
  }
  scanf("%d %d %d", &s, &t, &q);

  depth[q] = 1;
  if (!trySolution(s, t)) {
    if (!trySolution(t, s)) {
      printf("No chance!\n");
      return 0;
    }
  } 
  reverse(path.begin(), path.end());

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