Submission #1324169

#TimeUsernameProblemLanguageResultExecution timeMemory
1324169vneduPotemkin cycle (CEOI15_indcyc)C++17
20 / 100
1095 ms2032 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; }

    vector<char> isNeighbor(N+1, 0);
    const int UNVIS = -1;

    for (int s = 1; s <= N; ++s) {
        int deg = adj[s].size();
        if (deg < 2) continue;

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

        // multi-source BFS init
        vector<int> dist(N+1, UNVIS), src(N+1, -1), prev(N+1, -1);
        queue<int> q;
        for (int u : adj[s]) {
            dist[u] = 0;
            src[u] = u;
            prev[u] = -1;
            q.push(u);
        }

        while (!q.empty()) {
            int cur = q.front(); q.pop();
            for (int to : adj[cur]) {
                if (to == s) continue; // remove s
                // do not step into other neighbors of s (they are allowed only as sources)
                if (isNeighbor[to] && src[cur] != to) 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 a = src[cur], b = src[to]
                    int a = src[cur], b = src[to];
                    // build path from a -> ... -> cur
                    vector<int> p1;
                    int x = cur;
                    while (x != -1) { p1.push_back(x); if (x == a) break; x = prev[x]; }
                    if (p1.back() != a) continue; // safety
                    reverse(p1.begin(), p1.end()); // now a ... cur

                    // build path from b -> ... -> to
                    vector<int> p2;
                    x = to;
                    while (x != -1) { p2.push_back(x); if (x == b) break; x = prev[x]; }
                    if (p2.back() != b) continue;
                    reverse(p2.begin(), p2.end()); // now b ... to

                    // Construct cycle: s, p1 (a..cur), then reverse of p2 (to..b)
                    vector<int> cycle;
                    cycle.push_back(s);
                    for (int node : p1) cycle.push_back(node);
                    // append reversed p2 (from 'to' down to 'b')
                    for (int i = (int)p2.size()-1; i >= 0; --i) cycle.push_back(p2[i]);

                    // sanity: all nodes must be distinct
                    vector<char> seen(N+1, 0);
                    bool okDistinct = true;
                    for (int node : cycle) {
                        if (seen[node]) { okDistinct = false; break; }
                        seen[node] = 1;
                    }
                    if (!okDistinct) continue;

                    int k = cycle.size();
                    if (k < 4) continue;

                    // verify it's an induced cycle: no extra edges between non-consecutive vertices
                    bool induced = true;
                    for (int i = 0; i < k && induced; ++i) {
                        for (int j = i+1; j < k; ++j) {
                            if ( (j == i+1) || (i==0 && j==k-1) ) continue; // consecutive in cycle
                            if (adjMat[cycle[i]][cycle[j]]) { induced = false; break; }
                        }
                    }
                    if (!induced) continue;

                    // success: print cycle
                    for (int i = 0; i < k; ++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...