1 条题解

  • 0
    @ 2026-10-26 21:53:10

    思路与算法

    每组先确定家为首条街两端编号较小者,检查所有路口度数为偶。对街道编号建立邻接,按编号排序后用显式栈Hierholzer生成闭路;若未覆盖所有街或有奇点,输出题定失败语句。

    正确性说明

    输入保证街道互相连通,无向连通图具有欧拉回路当且仅当所有度数为偶。算法逐街使用唯一ID,并在退栈拼接各段,因此生成从家出发回家的全街回路。每街一次已经达到题目希望的最短游历条件;当前题面没有要求多解中只取某条。

    复杂度

    每组最多44点、1995街,邻接排序O(mlogm),构造与初始化O(n+m),空间O(n+m)。

    易错点

    自环在同一点加入两次邻接但边号只用一次。组结束是0 0,之后再一个0 0结束全部输入。失败文本大小写和标点保持原样;多解由街道连续性特判验收。

    参考代码(C++11)

    #include <bits/stdc++.h>
    using namespace std;
    int main() {
        ios::sync_with_stdio(false);
        cin.tie(nullptr);
        int x, y, z;
        while (cin >> x >> y && (x || y)) {
            vector<tuple<int, int, int>> e;
            int home = min(x, y);
            do {
                cin >> z;
                e.push_back({x, y, z});
                cin >> x >> y;
            } while (x || y);
            vector<vector<pair<int, int>>> g(45);
            int mx = 0;
            for (auto t : e) {
                int a = get<0>(t), b = get<1>(t), id = get<2>(t);
                g[a].push_back({b, id});
                g[b].push_back({a, id});
                mx = max(mx, id);
            }
            bool ok = true;
            for (auto &a : g) {
                if (a.size() % 2)
                    ok = false;
                sort(a.begin(), a.end(), [](pair<int, int> a, pair<int, int> b) {
                    return a.second < b.second;
                });
            }
            if (!ok) {
                cout << "Round trip does not exist.\n";
                continue;
            }
            vector<int> used(mx + 1), pos(45), st(1, home), edge, ans;
            while (!st.empty()) {
                int u = st.back();
                while (pos[u] < (int)g[u].size() && used[g[u][pos[u]].second])
                    pos[u]++;
                if (pos[u] < (int)g[u].size()) {
                    auto a = g[u][pos[u]++];
                    used[a.second] = 1;
                    st.push_back(a.first);
                    edge.push_back(a.second);
                } else {
                    st.pop_back();
                    if (!edge.empty()) {
                        ans.push_back(edge.back());
                        edge.pop_back();
                    }
                }
            }
            if (ans.size() != e.size()) {
                cout << "Round trip does not exist.\n";
                continue;
            }
            reverse(ans.begin(), ans.end());
            for (int i = 0; i < (int)ans.size(); i++)
                cout << ans[i] << (i + 1 == (int)ans.size() ? '\n' : ' ');
        }
    }
    
    • 1

    信息

    ID
    1870
    时间
    1000ms
    内存
    64MiB
    难度
    普及
    标签
    递交数
    0
    已通过
    0
    上传者