//gemini3.1pro #include #include #include #include #include #include using namespace std; // 辺の構造体 struct Edge { int to; int weight; int id; }; // 平方数判定 bool is_square(int n) { if (n < 0) return false; int r = round(sqrt(n)); return r * r == n; } int N; vector> adj; vector visited; vector best_path; // 深さ制限付きDFS (単純パスの探索) bool dfs(int u, int target, int sum, int depth, int max_depth, vector& path) { if (u == target) { if (is_square(sum)) { best_path = path; return true; } } if (depth == max_depth) return false; for (auto& edge : adj[u]) { int v = edge.to; if (!visited[v]) { visited[v] = true; path.push_back(edge.id); if (dfs(v, target, sum + edge.weight, depth + 1, max_depth, path)) return true; path.pop_back(); visited[v] = false; } } return false; } int main() { ios_base::sync_with_stdio(false); cin.tie(NULL); if (!(cin >> N)) return 0; int M = 2 * N - 3; if (N == 2) M = 1; // 乱数生成器 mt19937 rng(1337); while (true) { // 1から200の重みをシャッフル vector weights(200); iota(weights.begin(), weights.end(), 1); shuffle(weights.begin(), weights.end(), rng); adj.assign(N, vector()); struct EdgeDef { int u, v, w; }; vector edges; // グラフの構築 (2つの中心 0, 1 と、それに繋がる葉) if (N == 2) { edges.push_back({0, 1, weights[0]}); } else { edges.push_back({0, 1, weights[0]}); int w_idx = 1; for (int i = 2; i < N; ++i) { edges.push_back({0, i, weights[w_idx++]}); edges.push_back({1, i, weights[w_idx++]}); } } // 隣接リストの構築 for (int i = 0; i < M; ++i) { adj[edges[i].u].push_back({edges[i].v, edges[i].w, i}); adj[edges[i].v].push_back({edges[i].u, edges[i].w, i}); } bool all_ok = true; vector> ans_paths; // 全てのペア (i, j) について平方数パスが存在するか検証 for (int i = 0; i < N && all_ok; ++i) { for (int j = i + 1; j < N && all_ok; ++j) { bool found = false; // 反復深化DFS (短いパスから優先して探すことで高速化) for (int d = 1; d <= 5; ++d) { visited.assign(N, false); visited[i] = true; vector current_path; if (dfs(i, j, 0, 0, d, current_path)) { ans_paths.push_back(best_path); found = true; break; } } if (!found) { all_ok = false; } } } // 全てのペアで条件を満たした場合は出力して終了 if (all_ok) { // パスの長さを出力に含める一般的な形式 for (int i = 0; i < M; ++i) { // 辺の出力: u v 重み // ※ もし辺の出力フォーマットの指定があれば適宜書き換えてください // (問題文ではグラフの出力と Qi,j の出力が求められています) } // 以下、辺の情報と各ペアのパスを出力します // M, 次に各辺(u, v, c) cout << M << "\n"; for(int i=0; i