제출 #1324937

#제출 시각아이디문제언어결과실행 시간메모리
1324937mduc209Potemkin cycle (CEOI15_indcyc)C++20
60 / 100
222 ms1988 KiB
#include <iostream>
#include <vector>
#include <queue>
#include <algorithm>
#include <cstring>

using namespace std;

const int MAXN = 1005;

// Adjacency list for graph traversal
vector<int> adj[MAXN];
// Adjacency matrix for O(1) edge existence checks
bool adjMat[MAXN][MAXN];

// Array to store which neighbor of the start_node is the ancestor of the current node
// 0 implies unvisited in the current BFS run
int root_neighbor[MAXN]; 

// Array to reconstruct the path (stores predecessor)
int parent[MAXN];

void solve() {
    int N, R;
    if (!(cin >> N >> R)) return;

    // Clear graph data
    for (int i = 0; i <= N; ++i) {
        adj[i].clear();
        for (int j = 0; j <= N; ++j) adjMat[i][j] = false;
    }

    // Read Input
    for (int i = 0; i < R; ++i) {
        int u, v;
        cin >> u >> v;
        adj[u].push_back(v);
        adj[v].push_back(u);
        adjMat[u][v] = adjMat[v][u] = true;
    }

    // Iterate through each node considering it as the "start" (S) of a potential cycle
    for (int start_node = 1; start_node <= N; ++start_node) {
        // Reset the visited/root tracking array for this iteration
        // Using memset is efficient (O(N))
        memset(root_neighbor, 0, sizeof(int) * (N + 1));
        
        queue<int> q;
        
        // Mark start_node as visited to prevent traversing back to it
        root_neighbor[start_node] = -1; 

        // Initialize BFS with all neighbors of start_node
        for (int neighbor : adj[start_node]) {
            root_neighbor[neighbor] = neighbor; // The neighbor is the root of its branch
            parent[neighbor] = start_node;
            q.push(neighbor);
        }

        // Standard BFS
        while (!q.empty()) {
            int u = q.front();
            q.pop();

            for (int v : adj[u]) {
                if (v == start_node) continue; 

                if (root_neighbor[v] == 0) {
                    // Node v is unvisited
                    root_neighbor[v] = root_neighbor[u];
                    parent[v] = u;
                    q.push(v);
                } else {
                    // Node v is already visited. Check for collision.
                    // We only care if they come from different branches (different neighbors of start_node)
                    int r1 = root_neighbor[u];
                    int r2 = root_neighbor[v];

                    if (r1 != -1 && r2 != -1 && r1 != r2) {
                        // Collision between two different branches.
                        // Check if the roots (immediate neighbors of start_node) are connected.
                        // If (r1, r2) exists, then S-r1-r2-S is a triangle. We need a cycle >= 4.
                        // If they are NOT connected, we found a valid chordless cycle involving S.
                        
                        if (!adjMat[r1][r2]) {
                            // Valid cycle found!
                            
                            // Reconstruct the path.
                            // The cycle consists of: start_node -> ... -> u -> v -> ... -> start_node
                            
                            vector<int> cycle;
                            cycle.push_back(start_node);

                            // 1. Path from r1 to u (Left side of the loop)
                            vector<int> path_left;
                            int curr = u;
                            while (curr != start_node) {
                                path_left.push_back(curr);
                                curr = parent[curr];
                            }
                            // path_left is [u, ..., r1]. We need it in order [r1, ..., u].
                            for (int k = path_left.size() - 1; k >= 0; --k) {
                                cycle.push_back(path_left[k]);
                            }

                            // 2. Path from v to r2 (Right side of the loop)
                            // We traverse v -> ... -> r2. Since the cycle continues u -> v, 
                            // we append v and go up the parents towards r2.
                            curr = v;
                            while (curr != start_node) {
                                cycle.push_back(curr);
                                curr = parent[curr];
                            }
                            
                            // Print the result
                            for (int k = 0; k < cycle.size(); ++k) {
                                cout << cycle[k] << (k == cycle.size() - 1 ? "" : " ");
                            }
                            cout << endl;
                            return; // Solution found, exit immediately
                        }
                    }
                }
            }
        }
    }

    // If no such cycle is found after checking all start nodes
    cout << "no" << endl;
}

int main() {
    // Optimize I/O operations for performance
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    solve();
    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...