Submission #1324160

#TimeUsernameProblemLanguageResultExecution timeMemory
1324160vneduPotemkin cycle (CEOI15_indcyc)C++17
20 / 100
16 ms1832 KiB
#include <bits/stdc++.h>
using namespace std;

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    int N;
    long long R;
    if (!(cin >> N >> R)) return 0;
    vector<vector<int>> adj(N+1);
    vector<vector<char>> adjMat(N+1, vector<char>(N+1, 0));
    for (long long i = 0; i < R; ++i) {
        int a,b; cin >> a >> b;
        if (!adjMat[a][b]) {
            adj[a].push_back(b);
            adj[b].push_back(a);
            adjMat[a][b] = adjMat[b][a] = 1;
        }
    }
    if (N < 4) {
        cout << "NO\n";
        return 0;
    }

    // For each vertex v, try to find an induced cycle passing through v
    vector<char> isNeighbor(N+1);
    for (int v = 1; v <= N; ++v) {
        int deg = (int)adj[v].size();
        if (deg < 2) continue;

        // mark neighbors
        fill(isNeighbor.begin(), isNeighbor.end(), 0);
        for (int u : adj[v]) isNeighbor[u] = 1;

        // multi-source BFS from each neighbor u of v
        const int UNVIS = -1;
        vector<int> dist(N+1, UNVIS);
        vector<int> src(N+1, -1);
        vector<int> prev(N+1, -1);

        queue<int> q;
        for (int u : adj[v]) {
            dist[u] = 0;
            src[u] = u;
            prev[u] = -1;
            q.push(u);
        }

        bool found = false;
        int meet_u = -1, meet_w = -1; // meet at node w, between source src[w] and current src[cur]
        int meet_cur = -1;

        while (!q.empty() && !found) {
            int cur = q.front(); q.pop();
            for (int to : adj[cur]) {
                if (to == v) continue; // removed v from graph
                // don't pass through other neighbors of v (they may be start nodes only)
                if (isNeighbor[to] && src[cur] != to) {
                    // can visit 'to' only if it's the same source (i.e., starting node), else skip
                    continue;
                }
                if (dist[to] == UNVIS) {
                    dist[to] = dist[cur] + 1;
                    src[to] = src[cur];
                    prev[to] = cur;
                    q.push(to);
                } else if (src[to] != src[cur]) {
                    // found meeting between two different sources: src[cur] and src[to]
                    int a = src[cur];
                    int b = src[to];
                    int L_edges = dist[cur] + 1 + dist[to];
                    if (L_edges >= 2) { // means cycle length >= 4 when add v
                        // reconstruct path a ... cur -to ... b
                        vector<int> path1; // a -> ... -> cur
                        int x = cur;
                        while (x != -1) { path1.push_back(x); if (x == a) break; x = prev[x]; }
                        reverse(path1.begin(), path1.end()); // from a to cur

                        vector<int> path2; // to -> ... -> b
                        x = to;
                        while (x != -1) { path2.push_back(x); if (x == b) break; x = prev[x]; }
                        // path2 is from 'to' to 'b' (forward)
                        // final combined cycle: v, path1 (a..cur), to, path2_tail (nodes after 'to' towards b)
                        vector<int> cycle;
                        cycle.push_back(v);
                        for (int node : path1) cycle.push_back(node);
                        // we are currently at 'cur' then edge cur->to, so add 'to'
                        cycle.push_back(to);
                        // append remaining of path2 after 'to' (excluding the first element 'to')
                        for (size_t idx = 1; idx < path2.size(); ++idx) cycle.push_back(path2[idx]);

                        // remove possible duplicates (shouldn't exist) and check length
                        // verify cycle size >=4
                        if ((int)cycle.size() >= 4) {
                            // Optional sanity checks (edges and induced) could be omitted for speed
                            for (size_t i = 0; i < cycle.size(); ++i) {
                                if (i) cout << ' ';
                                cout << cycle[i];
                            }
                            cout << '\n';
                            return 0;
                        }
                    }
                }
            }
        }
    }

    cout << "NO\n";
    return 0;
}
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...