You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
|
|
|
|
#include <bits/stdc++.h>
|
|
|
|
|
|
|
|
|
|
using namespace std;
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
测试用例: 注意这里结点的序号不是连续的
|
|
|
|
|
5 5
|
|
|
|
|
1 4
|
|
|
|
|
4 7
|
|
|
|
|
7 18
|
|
|
|
|
18 20
|
|
|
|
|
20 18
|
|
|
|
|
*/
|
|
|
|
|
const int N = 1010;
|
|
|
|
|
|
|
|
|
|
multiset<int> v[N]; //邻接表,这就是存图用的multiset,
|
|
|
|
|
int ind[N];
|
|
|
|
|
// https://www.cnblogs.com/ucprer/p/12005710.html
|
|
|
|
|
// https://www.luogu.com.cn/blog/asuldb/ou-la-hui-lu-yu-ou-la-lu-jing
|
|
|
|
|
|
|
|
|
|
int n, m;
|
|
|
|
|
int path[N], idx;
|
|
|
|
|
|
|
|
|
|
//递归函数Hierholzer(x)
|
|
|
|
|
//插入回路法
|
|
|
|
|
void dfs(int x) {
|
|
|
|
|
//用一个迭代器依次遍历每一条边,因为multiset内部有序,所以这样先遍历到的边一定较小,就可以保证字典序较小
|
|
|
|
|
for (auto it = v[x].begin(); it != v[x].end(); it = v[x].begin()) {
|
|
|
|
|
v[x].erase(it);//这里删除一定要删除迭代器,如果直接erase变量的话,会将两点之间的多条路径一起删掉
|
|
|
|
|
//v[*it].erase(v[*it].find(x));//如果是无向图,也需要反向删除
|
|
|
|
|
dfs(*it);
|
|
|
|
|
}
|
|
|
|
|
//维护路径
|
|
|
|
|
path[++idx] = x;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int main() {
|
|
|
|
|
//采用邻接表建图
|
|
|
|
|
cin >> n >> m;
|
|
|
|
|
//m条边
|
|
|
|
|
for (int i = 1; i <= m; i++) {
|
|
|
|
|
int a, b;
|
|
|
|
|
cin >> a >> b;
|
|
|
|
|
ind[b]++; //入度
|
|
|
|
|
v[a].insert(b);
|
|
|
|
|
}
|
|
|
|
|
//假设给定的有向图是欧拉图,不需要检查,本代码作用是输出欧拉路径,把检查的代码省略掉了。
|
|
|
|
|
dfs(1);//开始递归
|
|
|
|
|
for (int i = idx; i; i--) printf("%d\n", path[i]);//倒着输出路径
|
|
|
|
|
return 0;
|
|
|
|
|
}
|