Submission #1259623

#TimeUsernameProblemLanguageResultExecution timeMemory
1259623mtshastaSailing Race (CEOI12_race)C++20
5 / 100
2307 ms4668 KiB
#include <bits/stdc++.h> using namespace std; const int MAXN = 505; const int INF = -1e9; int n, k; vector<int> adj[MAXN]; int dp[MAXN][MAXN][2]; // dp[i][j][dir] = max length from i to j in direction dir int best[MAXN][MAXN][2]; // best[i][j][dir] = max length starting at i, going dir, ending at j or beyond int main() { ios_base::sync_with_stdio(0); cin.tie(0); cin >> n >> k; // Read adjacency list for (int i = 0; i < n; i++) { int x; while (cin >> x && x != 0) { adj[i].push_back(x - 1); } } // Initialize DP arrays for (int i = 0; i < n; i++) { for (int j = 0; j < n; j++) { dp[i][j][0] = dp[i][j][1] = INF; best[i][j][0] = best[i][j][1] = INF; } } // Base case: direct shortcuts for (int i = 0; i < n; i++) { for (int next : adj[i]) { dp[i][next][0] = dp[i][next][1] = 1; } } // Compute DP for all intervals for (int len = 1; len < n; len++) { for (int i = 0; i < n; i++) { int j = (i + len) % n; int j_rev = (i - len + n) % n; // Clockwise direction if (find(adj[i].begin(), adj[i].end(), j) != adj[i].end()) { dp[i][j][1] = 1; } // Try splitting the interval for (int mid = (i + 1) % n; mid != j; mid = (mid + 1) % n) { dp[i][j][1] = max(dp[i][j][1], dp[i][mid][1] + dp[mid][j][1]); } // Counterclockwise direction if (find(adj[i].begin(), adj[i].end(), j_rev) != adj[i].end()) { dp[i][j_rev][0] = 1; } for (int mid = (i - 1 + n) % n; mid != j_rev; mid = (mid - 1 + n) % n) { dp[i][j_rev][0] = max(dp[i][j_rev][0], dp[i][mid][0] + dp[mid][j_rev][0]); } } } // Compute best arrays (allowing shortcuts at end) for (int i = 0; i < n; i++) { for (int j = 0; j < n; j++) { for (int dir = 0; dir < 2; dir++) { best[i][j][dir] = dp[i][j][dir]; if (dp[i][j][dir] > INF) { // Try using shortcuts from j for (int next : adj[j]) { int next_pos = dir ? (j + 1) % n : (j - 1 + n) % n; best[i][j][dir] = max(best[i][j][dir], dp[i][j][dir] + best[next][next_pos][1-dir]); } } } } } int ans_len = 0, ans_pos = 0; // Find maximum without cycles for (int i = 0; i < n; i++) { for (int j = 0; j < n; j++) { for (int dir = 0; dir < 2; dir++) { if (best[i][j][dir] > ans_len) { ans_len = best[i][j][dir]; ans_pos = i; } } } } // If k=1, try to form cycles if (k == 1) { for (int i = 0; i < n; i++) { for (int j = 0; j < n; j++) { for (int dir = 0; dir < 2; dir++) { if (dp[i][j][dir] <= 0) continue; // Try to close the cycle for (int back : adj[j]) { if (find(adj[back].begin(), adj[back].end(), i) != adj[back].end()) { int cycle_len = dp[i][j][dir] + 2; if (cycle_len > ans_len) { ans_len = cycle_len; ans_pos = back; } } } } } } } cout << ans_len << "\n" << ans_pos + 1 << "\n"; return 0; }
#Verdict Execution timeMemoryGrader output
Fetching results...