mayoko’s diary

プロコンとかいろいろ。

Codeforces Round #306 (Div. 2) D. Regular Bridge

解法

奇数の場合は写真のようにすれば構成できる。

f:id:mayokoex:20150605180706j:plain

偶数の場合は作ることは不可能(な気がする)。
あとで証明します。
uwiさんに教えてもらいました。


最初の主張(葉が必ずできる,というところ)は「二重辺連結成分分解」というワードで検索するとよくわからない人も納得できると思います。
で,次の主張はグラフ理論でとても基本的な定理「各頂点の次数の和は辺の数の2倍に等しい」という定理から示すことが出来ます。

uwiさん,ありがとうございました。

int main() {
    cin.tie(0);
    ios::sync_with_stdio(false);
    int k;
    cin >> k;
    if (k % 2 == 0) {
        cout << "NO" << endl;
        return 0;
    }
    vector<pii> ans;
    int n = 2*(2*k-1);
    cout << "YES" << endl;
    for (int i = 1; i < k; i++) {
        ans.push_back(pii(1, 1+i));
    }
    for (int i = 0; i < k-1; i++) {
        for (int j = 0; j < k-1; j++) {
            ans.push_back(pii(2+i, k+1+j));
        }
    }
    for (int i = 0; i < k/2; i++) {
        ans.push_back(pii(k+1+i*2, k+2+i*2));
    }
    ans.push_back(pii(1, k*2));
    for (int i = 1; i < k; i++) {
        ans.push_back(pii(2*k, 2*k+i));
    }
    for (int i = 0; i < k-1; i++) {
        for (int j = 0; j < k-1; j++) {
            ans.push_back(pii(2*k+1+i, 3*k+j));
        }
    }
    for (int i = 0; i < k/2; i++) {
        ans.push_back(pii(3*k+i*2, 3*k+1+i*2));
    }
    cout << n << " " << ans.size() << endl;
    for (auto p : ans) {
        cout << p.first << " " << p.second << endl;
    }
    return 0;
}