前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >小码匠的信息学江湖:【模板】欧拉路径

小码匠的信息学江湖:【模板】欧拉路径

作者头像
小码匠
发布2023-09-04 15:46:30
2620
发布2023-09-04 15:46:30
举报
文章被收录于专栏:小码匠和老码农

大家好!我是小码匠。

这是我的编程江湖,这里没有九阴白骨爪,也没有降龙十八掌。

但是,老码农的打狗棒舞的是熠熠生辉,代码敲不好,他就要给我展示打狗棒法了。

本系列是模版系列,会整理

  • 题目链接地址
  • 参考资料
  • AC代码
  • 自己挖坑(部分题目有)

关于思路大家可参照题目信息的链接地址或者相关书籍,文章旨在分享代码。

题目信息

  • https://www.luogu.com.cn/problem/P7771
    • 题解:https://www.luogu.com.cn/problem/solution/P7771

参考资料

  • 欧拉图
    • https://oi-wiki.org/graph/euler/

题目描述

求有向图字典序最小的欧拉路径。

输入格式

第一行两个整数 n,m 表示有向图的点数和边数。

接下来 m 行每行两个整数 u,v 表示存在一条 u→v 的有向边。

输出格式

如果不存在欧拉路径,输出一行 No

否则输出一行 m+1 个数字,表示字典序最小的欧拉路径。

输入输出样例

输入 #1复制

代码语言:javascript
复制
4 6
1 3
2 1
4 2
3 3
1 2
3 4

输出 #1复制

代码语言:javascript
复制
1 2 1 3 3 4 2

输入 #2复制

代码语言:javascript
复制
5 5
1 2
3 5
4 3
3 4
2 3

输出 #2复制

代码语言:javascript
复制
1 2 3 4 3 5

输入 #3复制

代码语言:javascript
复制
4 3
1 2
1 3
1 4

输出 #3复制

代码语言:javascript
复制
No

说明/提示

对于 50% 的数据,

n,m≤10^3

对于 100% 的数据,

1≤u,v≤n≤10^5,m≤2×10^5

保证将有向边视为无向边后图连通。

AC代码

代码语言:javascript
复制
// Copyright (C) 2021-2028 coder-oldgeek.com All rights reserved.
// 题目: 【模板】欧拉路径
// 链接: https://www.luogu.com.cn/problem/P7771
// 难度: 普及+/提高
// 提交:
// 题解:
// - https://www.luogu.com.cn/problem/solution/P7771
#include <bits/stdc++.h>

using namespace std;

#define endl '\n';

const int MAXN = 100010;
int vis[MAXN];

struct node {
    int in, out;
} degree[MAXN];

stack<int> st;
vector<int> g[MAXN];

void dfs(int now) {
    for (int i = vis[now]; i < g[now].size(); i = vis[now]) {
        vis[now] = i + 1;
        dfs(g[now][i]);
    }
    st.push(now);
}

void best_coder() {
    // 提升cin、cout效率
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    int n, m;
    cin >> n >> m;
    for (int i = 1; i <= m; ++i) {
        int u, v;
        cin >> u >> v;
        g[u].push_back(v);
        ++degree[v].in;
        ++degree[u].out;
    }
    for (int i = 1; i <= n; ++i) {
        sort(g[i].begin(), g[i].end());
    }
    int s = 1;
    pair<int, int> cnt = {0, 0};
    bool is = true;
    for (int i = 1; i <= n; ++i) {
        if (degree[i].in != degree[i].out) {
            is = false;
            if (degree[i].out - degree[i].in == 1) {
                ++cnt.second;
                s = i;
            } else if (degree[i].in - degree[i].out == 1) {
                ++cnt.first;
            } else {
                cout << "No";
                return;
            }
        }
    }
    if ((!is) && !(cnt.first == cnt.second && cnt.first == 1)) {
        cout << "No";
        return;
    }
    dfs(s);
    while (!st.empty()) {
        cout << st.top() << " ";
        st.pop();
    }
}

void happy_coder() {
    // 提升cin、cout效率
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
}

int main() {
    // 小码匠
    best_coder();

    // 最优解
    // happy_coder();

    // 返回
    return 0;
}
本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2023-09-03,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 小码匠和老码农 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 题目信息
  • 参考资料
  • 题目描述
  • 输入格式
  • 输出格式
  • 输入输出样例
  • 说明/提示
    • AC代码
    领券
    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档