Pagini recente » Cod sursa (job #3358816) | Monitorul de evaluare | Monitorul de evaluare | Monitorul de evaluare | Cod sursa (job #3358619)
#include <bits/stdc++.h>
using namespace std;
ifstream fin("santa.in");
ofstream fout("santa.out");
int n, m, S, E, Q;
vector<int> adj[45005];
int dfn[45005], low[45005], timer;
vector<pair<int, int>> st;
vector<vector<int>> bccs;
void dfs(int u, int p = 0) {
dfn[u] = low[u] = ++timer;
for (int v : adj[u]) {
if (v == p) continue;
if (dfn[v]) {
low[u] = min(low[u], dfn[v]);
if (dfn[v] < dfn[u]) st.push_back({u, v});
} else {
st.push_back({u, v});
dfs(v, u);
low[u] = min(low[u], low[v]);
if (low[v] >= dfn[u]) {
vector<int> bcc;
while (true) {
auto edge = st.back();
st.pop_back();
bcc.push_back(edge.first);
bcc.push_back(edge.second);
if (edge.first == u && edge.second == v) break;
}
sort(bcc.begin(), bcc.end());
bcc.erase(unique(bcc.begin(), bcc.end()), bcc.end());
bccs.push_back(bcc);
}
}
}
}
bool has_edge(int u, int v) {
auto it = lower_bound(adj[u].begin(), adj[u].end(), v);
return it != adj[u].end() && *it == v;
}
vector<int> bct[90005];
vector<int> bct_path;
bool get_path(int u, int p) {
bct_path.push_back(u);
if (u == E) return true;
for (int v : bct[u]) {
if (v != p && get_path(v, u)) return true;
}
bct_path.pop_back();
return false;
}
int memo[32768][16];
int memo_timer[32768][16];
int current_timer = 0;
int next_node[32768][16];
int cur_k, target_idx;
int adj_mask[16];
bool solve_dp(int mask, int u) {
if (mask == (1 << cur_k) - 1) {
return (target_idx == -1 || u == target_idx);
}
if (memo_timer[mask][u] == current_timer) return memo[mask][u];
memo_timer[mask][u] = current_timer;
int available = adj_mask[u] & ~mask;
while (available) {
int v = __builtin_ctz(available);
available &= (available - 1);
if (solve_dp(mask | (1 << v), v)) {
next_node[mask][u] = v;
return memo[mask][u] = 1;
}
}
return memo[mask][u] = 0;
}
vector<int> final_ans;
vector<int> cur_bcc_nodes;
bool try_chain(vector<int>& B, vector<int>& C) {
bool q_found = false;
for (int x : bccs[B[0]]) {
if (x == Q) q_found = true;
}
if (!q_found) return false;
vector<int> path;
for (int i = 0; i < (int)B.size(); i++) {
int start_node = (i == 0) ? Q : C[i];
int end_node = (i == (int)B.size() - 1) ? -1 : C[i + 1];
cur_bcc_nodes = bccs[B[i]];
cur_k = cur_bcc_nodes.size();
if (cur_k > 16) return false;
int start_idx = -1;
target_idx = -1;
for (int j = 0; j < cur_k; j++) {
if (cur_bcc_nodes[j] == start_node) start_idx = j;
if (cur_bcc_nodes[j] == end_node) target_idx = j;
}
if (start_idx == -1) return false;
if (end_node != -1 && target_idx == -1) return false;
for (int u = 0; u < cur_k; u++) {
adj_mask[u] = 0;
for (int v = 0; v < cur_k; v++) {
if (u != v && has_edge(cur_bcc_nodes[u], cur_bcc_nodes[v])) {
adj_mask[u] |= (1 << v);
}
}
}
current_timer++;
if (!solve_dp(1 << start_idx, start_idx)) return false;
vector<int> bcc_path;
int mask = 1 << start_idx;
int u = start_idx;
while (mask != (1 << cur_k) - 1) {
bcc_path.push_back(cur_bcc_nodes[u]);
int v = next_node[mask][u];
mask |= (1 << v);
u = v;
}
bcc_path.push_back(cur_bcc_nodes[u]);
if (i == 0) {
path = bcc_path;
} else {
for (int j = 1; j < (int)bcc_path.size(); j++) {
path.push_back(bcc_path[j]);
}
}
}
final_ans = path;
return true;
}
int main() {
fin >> n >> m;
for (int i = 1; i <= m; i++) {
int u, v;
fin >> u >> v;
adj[u].push_back(v);
adj[v].push_back(u);
}
fin >> S >> E >> Q;
for (int i = 1; i <= n; i++) {
sort(adj[i].begin(), adj[i].end());
}
dfs(S);
for (int i = 0; i < (int)bccs.size(); i++) {
for (int u : bccs[i]) {
bct[u].push_back(n + 1 + i);
bct[n + 1 + i].push_back(u);
}
}
if (!get_path(S, 0)) {
fout << "No chance\n";
return 0;
}
vector<int> b_seq, c_seq;
for (int i = 0; i < (int)bct_path.size(); i++) {
if (i % 2 == 1) b_seq.push_back(bct_path[i] - n - 1);
else c_seq.push_back(bct_path[i]);
}
if (b_seq.empty()) {
if (Q == S) {
fout << 1 << "\n" << S << "\n";
} else {
fout << "No chance\n";
}
return 0;
}
if (try_chain(b_seq, c_seq)) {
fout << final_ans.size() << "\n";
for (int i = 0; i < (int)final_ans.size(); i++) {
fout << final_ans[i] << (i + 1 == (int)final_ans.size() ? "" : " ");
}
fout << "\n";
return 0;
}
reverse(b_seq.begin(), b_seq.end());
reverse(c_seq.begin(), c_seq.end());
if (try_chain(b_seq, c_seq)) {
fout << final_ans.size() << "\n";
for (int i = 0; i < (int)final_ans.size(); i++) {
fout << final_ans[i] << (i + 1 == (int)final_ans.size() ? "" : " ");
}
fout << "\n";
return 0;
}
fout << "No chance\n";
return 0;
}