結果
問題 |
No.3071 Double Speedrun
|
ユーザー |
![]() |
提出日時 | 2025-05-14 12:59:18 |
言語 | C++17 (gcc 13.3.0 + boost 1.87.0) |
結果 |
WA
|
実行時間 | - |
コード長 | 5,758 bytes |
コンパイル時間 | 741 ms |
コンパイル使用メモリ | 86,092 KB |
実行使用メモリ | 7,848 KB |
最終ジャッジ日時 | 2025-05-14 13:00:22 |
合計ジャッジ時間 | 1,524 ms |
ジャッジサーバーID (参考情報) |
judge3 / judge5 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
sample | AC * 1 WA * 2 |
other | WA * 14 |
ソースコード
#include <iostream> #include <vector> #include <numeric> #include <algorithm> int main() { // Use faster I/O operations std::ios_base::sync_with_stdio(false); std::cin.tie(NULL); int L, R, M; // Read the number of vertices in V1 (L), V2 (R), and the number of edges (M) std::cin >> L >> R >> M; // Check constraints for dimensions. Problem statement guarantees L, R >= 1, M >= 1. // If L=0 or R=0, it might violate bipartite graph definition or constraints. Assuming valid inputs. // Store the edges. Each edge connects a vertex from V1 (0..L-1) and V2 (0..R-1). // We will map vertices from V2 to indices L..L+R-1 for a unified vertex index space 0..L+R-1. std::vector<std::pair<int, int>> edges(M); // Store the degree of each vertex. Initialize all degrees to 0. std::vector<int> degree(L + R, 0); // Read M edges from input for (int i = 0; i < M; ++i) { int u, v_raw; // u is vertex index in V1, v_raw is vertex index in V2 std::cin >> u >> v_raw; // Assuming 0-based indexing based on constraints 0 <= a_i < L, 0 <= b_i < R. // Map vertex index from V2 (v_raw) to the unified index space [L, L+R-1] int v = L + v_raw; // Store the edge with unified indices edges[i] = {u, v}; // Increment degrees of the connected vertices degree[u]++; degree[v]++; } // Compute the minimum degree (delta) of the graph. // Initialize delta with a value larger than any possible degree (e.g., M+1). int delta = M + 1; // The problem states "孤立点は存在しない" (isolated vertices do not exist). // This implies that every vertex in V1 U V2 must have a degree of at least 1. // Find the minimum degree among all L+R vertices. for (int i = 0; i < L + R; ++i) { // If degree[i] == 0, it contradicts the problem statement. Assume degree[i] >= 1 for all i. delta = std::min(delta, degree[i]); } // If L+R = 0, this loop doesn't run. But constraints L, R >= 1 ensure L+R >= 2. // If M = 0, degrees are all 0. But constraints M >= 1 ensure at least one edge. // Therefore, delta should be correctly computed and delta >= 1. // Vector to store the color assigned to each edge. Size M. std::vector<int> edge_colors(M); // Use a 2D vector `needed` to track which colors are still required for each vertex. // `needed[v][k]` is true if vertex `v` still needs an incident edge with color `k`. // Initialize all `needed` flags to true, meaning initially all vertices need all colors 0..delta-1. // Dimensions: (L+R) vertices x delta colors. std::vector<std::vector<bool>> needed(L + R, std::vector<bool>(delta, true)); // Apply the greedy coloring strategy: Iterate through edges and assign colors. for (int i = 0; i < M; ++i) { int u = edges[i].first; // First endpoint of the i-th edge int v = edges[i].second; // Second endpoint of the i-th edge int best_k = -1; // Variable to store the best color found for the current edge int max_score = -1; // Variable to store the maximum score achieved by any color // Iterate through all possible colors k from 0 to delta-1 for (int k = 0; k < delta; ++k) { // Calculate the score for color k. The score is the count of endpoints (u, v) that still need color k. // Score can be 0, 1, or 2. int current_score = (needed[u][k] ? 1 : 0) + (needed[v][k] ? 1 : 0); // If the current color k has a higher score than the max score found so far, // update max_score and set best_k to k. if (current_score > max_score) { max_score = current_score; best_k = k; } // If current_score is equal to max_score, we apply a tie-breaking rule: choose the smallest k. // Since we iterate k from 0 upwards, the first k that achieves the max_score is automatically the smallest. // We only need to handle the initialization case where best_k is -1. // If max_score is 0 initially, the first k=0 will set max_score=0, best_k=0. // If subsequent k also have score 0, best_k remains 0 (the minimum). else if (current_score == max_score && best_k == -1) { // Assign the first k encountered if max_score is 0 or hasn't been updated yet. best_k = k; } } // After checking all colors, best_k holds the chosen color for edge i. // If delta is 0 (which shouldn't happen) or some other unexpected state leads to best_k = -1, default to color 0. if (best_k == -1) { best_k = 0; } // Assign the chosen color to the current edge i edge_colors[i] = best_k; // Update the 'needed' status for the endpoints u and v. // Once an edge of color best_k is incident to u (or v), they no longer strictly 'need' it // for the purpose of maximizing the score in subsequent steps. // The final state must satisfy the condition that all vertices are incident to all colors. // The theorem guarantees this is possible, and this greedy strategy finds one such coloring. needed[u][best_k] = false; needed[v][best_k] = false; } // Output the results. // First line: the maximum number of colors K used, which is delta. std::cout << delta << "\n"; // Following M lines: the color assigned to each edge i (0-indexed color from 0..delta-1). for (int i = 0; i < M; ++i) { std::cout << edge_colors[i] << "\n"; } return 0; }