結果

問題 No.3585 Make Ends Meet (Easy)
コンテスト
ユーザー marc2825
提出日時 2026-05-25 09:38:00
言語 C++17
(gcc 15.2.0 + boost 1.90.0)
コンパイル:
g++-15 -O2 -lm -std=c++17 -Wuninitialized -DONLINE_JUDGE -o a.out _filename_
実行:
./a.out
結果
AC  
実行時間 2 ms / 2,000 ms
コード長 2,414 bytes
記録
記録タグの例:
初AC ショートコード 純ショートコード 純主流ショートコード 最速実行時間
コンパイル時間 1,304 ms
コンパイル使用メモリ 222,072 KB
実行使用メモリ 5,888 KB
最終ジャッジ日時 2026-07-10 20:51:49
合計ジャッジ時間 3,380 ms
ジャッジサーバーID
(参考情報)
judge2_0 / judge1_0
このコードへのチャレンジ
(要ログイン)
ファイルパターン 結果
sample AC * 2
other AC * 48
権限があれば一括ダウンロードができます

ソースコード

diff #
raw source code

#include <bits/stdc++.h>
using namespace std;

int N, M, K;
vector<vector<bool>> keep;

void print_no() {
    cout << "No\n";
}

void print_yes() {
    cout << "Yes\n";

    for (int u = 1; u <= N; ++u) {
        for (int v = u + 1; v <= N; ++v) {
            if (!keep[u][v]) {
                cout << v << ' ' << u << '\n';
            }
        }
    }
}


int main() {
    cin >> N >> M >> K;

    int T = N * (N - 1) / 2;
    int E = T - M; // number of edges to keep

    keep.assign(N + 1, vector<bool>(N + 1, false));

    if (K == 1) {
        // The distance is 1 iff the direct edge (1, N) remains.
        if (E == 0) {
            print_no();
            return 0;
        }

        keep[1][N] = true;
        E--;

        for (int u = 1; u <= N && E > 0; ++u) {
            for (int v = u + 1; v <= N && E > 0; ++v) {
                if (u == 1 && v == N) continue;

                keep[u][v] = true;
                E--;
            }
        }

        print_yes();
        return 0;
    }

    // K >= 2.
    // Use the path 1 - 2 - ... - K - N as the mandatory shortest path.
    int U = N - K - 1; // number of vertices not on the path

    int min_keep = K;
    int max_keep = K + 3 * U + U * (U - 1) / 2;

    if (!(min_keep <= E && E <= max_keep)) {
        print_no();
        return 0;
    }

    // Keep the mandatory path edges.
    for (int i = 1; i < K; ++i) {
        keep[i][i + 1] = true;
        E--;
    }
    keep[K][N] = true;
    E--;

    vector<pair<int, int>> free_edges;

    // Extra vertices are K+1, K+2, ..., N-1.
    // Each of them can be connected to three consecutive path vertices.
    for (int x = K + 1; x <= N - 1; ++x) {
        free_edges.push_back({1, x});
        free_edges.push_back({2, x});

        if (K == 2) {
            // Path vertices are 1, 2, N.
            free_edges.push_back({x, N});
        } else {
            // Path vertices include 1, 2, 3.
            free_edges.push_back({3, x});
        }
    }

    // Extra vertices can be connected freely among themselves.
    for (int x = K + 1; x <= N - 1; ++x) {
        for (int y = x + 1; y <= N - 1; ++y) {
            free_edges.push_back({x, y});
        }
    }

    // Add arbitrary free edges until exactly E additional edges are kept.
    for (auto [u, v] : free_edges) {
        if (E == 0) break;

        keep[u][v] = true;
        E--;
    }

    print_yes();
    return 0;
}
0