Pagini recente » Profil AndreiM1998 | Statistici Ros Antonio (ros_antonio) | Cod sursa (job #1132743) | Cod sursa (job #2130014) | Cod sursa (job #1829940)
#include <fstream>
#include <vector>
#include <cstring>
#include <algorithm>
using namespace std;
ifstream fin ("santa.in"); ofstream fout ("santa.out");
typedef vector< int > graf;
const int nmax = 45e3 + 5;
const int mmax = 13e4 + 5;
const int lim = 15;
const int inf = 1 << 30;
int n, S, E, Q;
bool viz[nmax + 1], posibil[nmax + 1], ok[mmax + 1];
int h[nmax + 1], d[nmax + 1], last[nmax + 1], p[nmax + 1], unde[nmax + 1];
int r[(1 << lim)][lim + 1];
int t[nmax + 1];
graf g[nmax + 1];
int nrc;
vector< int > c[mmax + 1];
vector< pair<int, int> > gc[mmax + 1];
vector< pair<int, int> > ord;
void dfs (int nod) {
d[ nod ] = inf;
viz[ nod ] = 1;
for (auto i : g[ nod ]) {
if (viz[ i ] == 0) {
h[ i ] = h[ nod ] + 1;
dfs( i );
d[ nod ] = min(d[ nod ], d[ i ]);
} else {
d[ nod ] = min(d[ nod ], h[ i ]);
}
}
}
void calc_comp (int nod, int x) {
if (p[ nod ] == 0) p[ nod ] = x;
c[ x ].push_back( nod ); last[ nod ] = x;
viz[ nod ] = 1;
for (auto i : g[ nod ]) {
if (viz[ i ] == 0) {
if (d[ i ] >= h[ nod ]) {
gc[ x ].push_back(make_pair(nrc + 1, nod));
gc[nrc + 1].push_back(make_pair(x, nod));
++ nrc;
c[ nrc ].push_back( nod ); last[ nod ] = nrc;
calc_comp(i, nrc);
} else {
calc_comp(i, x);
}
}
}
}
void care_sunt_ok (int nod, int dest, int &gasit, int k) {
viz[ nod ] = 1;
if (nod == dest) {
gasit = 1;
} else {
for (auto i : gc[ nod ]) {
if (viz[ i.first ] == 0) {
care_sunt_ok(i.first, dest, gasit, i.second);
if (gasit == 1) {
break;
}
}
}
}
ok[ nod ] = gasit;
if (gasit == 1) {
ord.push_back(make_pair(nod, k));
}
}
void solve () {
reverse(ord.begin(), ord.end());
posibil[ Q ] = 1;
for (int shp = 0; shp < (int)ord.size(); ++ shp) {
memset(r, -1, sizeof(r));
memset(unde, -1, sizeof(unde));
int nod = ord[ shp ].first, x = ord[ shp ].second;
for (int i = 0; i < (int)c[ nod ].size(); ++ i) {
unde[ c[ nod ][ i ] ] = i;
}
x = unde[ x ];
if (posibil[ c[ nod ][ x ] ] == 0) return ;
r[(1 << x)][ x ] = inf;
int aux = (int)c[ nod ].size();
for (int st = (1 << x) + 1; st < (1 << aux); ++ st) {
if ((st & (1 << x)) == 0) continue;
for (int j = 0; j < aux; ++ j) {
if ((st & (1 << j)) == 0) continue;
int stn = st - (1 << j);
for (auto i : g[ c[ nod ][ j ] ]) {
if (unde[ i ] != -1 && (stn & (1 << unde[ i ]))) {
if (r[ stn ][ unde[ i ] ] != -1) {
r[ st ][ j ] = unde[ i ];
break;
}
}
}
}
}
for (int i = 0; i < aux; ++ i) {
posibil[ c[ nod ][ i ] ] = (r[(1 << aux) - 1][ i ] != -1);
}
if (shp != (int)ord.size() - 1) {
aux = unde[ ord[shp + 1].second ];
int stk = (1 << (int)c[ nod ].size()) - 1;
while (aux != x && r[ stk ][ aux ] != -1) {
int y = r[ stk ][ aux ];
t[ c[ nod ][ y ] ] = c[ nod ][ aux ];
stk -= (1 << aux);
aux = y;
}
}
}
}
int main() {
int m;
fin >> n >> m;
for (int i = 1; i <= m; ++ i) {
int x, y;
fin >> x >> y;
g[ x ].push_back( y ); g[ y ].push_back( x );
}
fin >> S >> E >> Q;
dfs( S );
nrc = 1;
memset(viz, 0, sizeof(viz));
calc_comp(S, 1);
if (c[ 1 ].size() == 1) {
p[ S ] = 2;
}
int ind = -1;
if (p[ S ] > 0 && p[ E ] > 0) {
for (auto i : c[ p[ S ] ]) {
if (i == Q) {
ind = p[ S ]; break;
}
}
for (auto i : c[ p[ E ] ]) {
if (i == Q) {
ind = p[ E ]; break;
}
}
}
if (ind == -1) {
fout << "No chance\n";
} else {
memset(viz, 0, sizeof(viz));
int aux = 0;
if (c[ 1 ].size() == 1) viz[ 1 ] = 1;
if (ind == p[ S ]) care_sunt_ok(p[ S ], p[ E ], aux, Q);
else care_sunt_ok(p[ E ], p[ S ], aux, Q);
solve();
int fin_pos = -1;
ind = ord.back().first;
aux = (int)c[ ind ].size();
for (int i = 0; i < aux; ++ i) {
if (r[(1 << aux) - 1][ i ] != -1) {
fin_pos = i;
}
}
if (fin_pos == -1) {
fout << "No chance\n";
} else {
aux = (1 << aux) - 1;
int x = fin_pos;
while (r[ aux ][ x ] != -1 && r[ aux ][ x ] != inf) {
int y = r[ aux ][ x ];
t[ c[ ind ][ y ] ] = c[ ind ][ x ];
aux -= (1 << x);
x = y;
}
vector< int > ans;
fin_pos = c[ ind ][fin_pos];
while (Q != fin_pos) {
ans.push_back( Q );
Q = t[ Q ];
}
ans.push_back(fin_pos);
fout << ans.size() << "\n";
for (auto i : ans) {
fout << i << " ";
}
fout << "\n";
}
}
fin.close();
fout.close();
return 0;
}