Submission #1324158

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

    // MCS (Maximum Cardinality Search)
    vector<int> weight(N+1, 0);
    vector<char> used(N+1, 0);
    vector<int> seq; seq.reserve(N);
    for (int iter = 0; iter < N; ++iter) {
        int pick = -1;
        int best = -1;
        for (int v = 1; v <= N; ++v) if (!used[v]) {
            if (weight[v] > best) { best = weight[v]; pick = v; }
        }
        if (pick == -1) break;
        used[pick] = 1;
        seq.push_back(pick);
        for (int w : adj[pick]) if (!used[w]) weight[w]++;
    }

    // seq is selection order; reverse to get PEO candidate
    reverse(seq.begin(), seq.end());
    vector<int> pos(N+1, 0);
    for (int i = 0; i < (int)seq.size(); ++i) pos[seq[i]] = i+1; // positions 1..N

    // Check for clique property of later neighbors
    for (int v = 1; v <= N; ++v) {
        vector<int> later;
        for (int u : adj[v]) if (pos[u] > pos[v]) later.push_back(u);
        if (later.size() <= 1) continue;
        // find parent = later neighbor with minimal pos (i.e., smallest index among later)
        int parent = later[0];
        for (int u : later) if (pos[u] < pos[parent]) parent = u;
        // check all later neighbors are adjacent to parent
        for (int u : later) {
            if (u == parent) continue;
            if (!adjMat[u][parent]) {
                // Found witness: v has later neighbors parent and u not adjacent.
                // BFS from parent to u using only vertices w with pos[w] >= pos[parent]
                vector<int> prev(N+1, -1);
                vector<char> vis(N+1, 0);
                queue<int> q;
                q.push(parent); vis[parent]=1; prev[parent] = -1;
                while (!q.empty()) {
                    int cur = q.front(); q.pop();
                    if (cur == u) break;
                    for (int w : adj[cur]) {
                        if (!vis[w] && pos[w] >= pos[parent]) {
                            vis[w] = 1;
                            prev[w] = cur;
                            q.push(w);
                        }
                    }
                }
                if (!vis[u]) continue; // theoreticaly shouldn't happen, but safe
                // reconstruct path parent -> ... -> u
                vector<int> path;
                for (int x = u; x != -1; x = prev[x]) path.push_back(x);
                reverse(path.begin(), path.end()); // path[0] == parent, last == u
                // Form cycle: v + path
                // path length (nodes) >= 3 because parent and u not adjacent -> cycle length >= 4
                cout << v;
                for (int node : path) cout << ' ' << node;
                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...