大家好!我是小码匠。
这是我的编程江湖,这里没有九阴白骨爪,也没有降龙十八掌。
但是,老码农的打狗棒舞的是熠熠生辉,代码敲不好,他就要给我展示打狗棒法了。
本系列是模版系列,会整理
关于思路大家可参照题目信息的链接地址或者相关书籍,文章旨在分享代码。
求有向图字典序最小的欧拉路径。
第一行两个整数 n,m 表示有向图的点数和边数。
接下来 m 行每行两个整数 u,v 表示存在一条 u→v 的有向边。
如果不存在欧拉路径,输出一行 No
。
否则输出一行 m+1 个数字,表示字典序最小的欧拉路径。
输入 #1复制
4 6
1 3
2 1
4 2
3 3
1 2
3 4
输出 #1复制
1 2 1 3 3 4 2
输入 #2复制
5 5
1 2
3 5
4 3
3 4
2 3
输出 #2复制
1 2 3 4 3 5
输入 #3复制
4 3
1 2
1 3
1 4
输出 #3复制
No
对于 50% 的数据,
。
对于 100% 的数据,
。
保证将有向边视为无向边后图连通。
// 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;
}