Cod sursa(job #3370386)

Utilizator Radu_BicliBiclineru Radu Radu_Bicli Data 25 octombrie 2026 21:40:39
Problema Santa Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.62 kb
#include <bits/stdc++.h>

using namespace std;

#define USE_STD_IO 0
#if USE_STD_IO
    #define fin cin
    #define fout cout
#else
    ifstream fin("santa.in");
    ofstream fout("santa.out");
#endif // USE_STD_IO

const int MAX = 45002;

int n, m, i, q, s, e;
int niv[MAX], nivMi[MAX];

bool inComp[MAX];
stack<array<int, 2>> stiv;
vector<int> comp, drum;

vector<int> gr[MAX];

int marOrg;

static inline int Min(const int a, const int b) {
	return (a < b ? a : b);
}

static inline bool Back(const int pas, const int nod, const int tata) {
	inComp[nod] = false;
	if(1 < pas) drum.push_back(nod);
	if((int)marOrg == pas) {
		if(nod == tata) return true;
		drum.pop_back();
		inComp[nod] = true;
		return false;
	}

	for(const int vec : gr[nod]) {
		if(inComp[vec] && ((int)marOrg - 1 == pas || vec != tata) && Back(pas + 1, vec, tata)) return true;
	}
	drum.pop_back();
	inComp[nod] = true;
	return false;
}

static inline bool DFSBiconex(const int nod, const int s, const int e, bool &gasit) {
	nivMi[nod] = niv[nod];
	bool ok = (nod == e);

	for(const int vec : gr[nod]) {
		if(nod == q || niv[vec] != niv[nod] - 1) {
			if(0 != niv[vec]) {
				nivMi[nod] = Min(niv[vec], nivMi[nod]);
			}
			else { // 0 == niv[vec]
				niv[vec] = 1 + niv[nod];
				stiv.push({nod, vec});

				const bool okVec = DFSBiconex(vec, s, e, gasit);

				nivMi[nod] = Min(nivMi[nod], nivMi[vec]);
				
				if(niv[nod] <= nivMi[vec]) { 
					comp = {nod, vec};
					while(false == stiv.empty() && array<int, 2>{nod, vec} != stiv.top()) {
						comp.push_back(stiv.top()[1]);
						stiv.pop();
					}
					stiv.pop();

					marOrg = comp.size();
					if(okVec) {
						for(const int cur : comp) inComp[cur] = true;
						inComp[drum.back()] = false;

						gasit &= (nod != q || inComp[s]);
						gasit &= Back(1, drum.back(), nod);
						for(const int cur : comp) inComp[cur] = false;
					}
				}
				ok |= okVec;
			}
		}
	}
	return ok;
}

static inline bool Incearca(const int s, const int e) {
    bool gasit_val = true;
    memset(niv, 0, (n + 1) * sizeof(int));
    memset(nivMi, 0, (n + 1) * sizeof(int));
    niv[q] = 1;
    drum = {e};
    DFSBiconex(q, s, e, gasit_val);
    return gasit_val;
}

int main() {
    #if USE_STD_IO
        ios_base::sync_with_stdio(false);
    #endif // USE_STD_IO
    fin.tie(nullptr);
    fout.tie(nullptr);

	fin >> n >> m;
	for(i = 1; i <= m; i++) {
		int x, y;
		fin >> x >> y;
		gr[x].push_back(y);
		gr[y].push_back(x);
	}
	fin >> s >> e >> q;

	if(!Incearca(s, e)) {
		if(!Incearca(e, s)) {
			return 0;
		}
	}

	reverse(drum.begin(), drum.end());
	fout << drum.size() << '\n';
	for(const int cur : drum) fout << cur << ' ';
	fout << '\n';
	
    return 0;
}