欧拉回路逐步插入回路法(Hierholzer 算法)
题目要求字典序最小,所以找最小的起点,注意优先选择奇数度的点为起点。
#include <iostream>
#include <stack>
#include <algorithm>
#include <vector>
using namespace std;
stack<int> ans;
int head[510];
int Enum = 0;
int deg[510];
struct Edge{
int to;
int next;
};
Edge edge[2060];
bool vis[2060];
int Map[2060];
bool cmp(pair<int, int> a, pair<int, int> b)
{
return a.second < b.second;
}
void add(int a, int b)
{
++Enum;
edge[Enum].to = b;
edge[Enum].next = head[a];
head[a] = Enum;
}
void Hierholzer(int node)
{
vector<pair<int, int> > q;
for(int i = head[node]; i != 0; i = edge[i].next)
{
q.push_back(make_pair(i, edge[i].to));
}
sort(q.begin(), q.end(), cmp);
for(auto i:q)
{
if(!vis[i.first]&&!vis[Map[i.first]])
{
vis[i.first] = true;
vis[Map[i.first]] = true;
Hierholzer(i.second);
}
}
ans.push(node);
}
int main()
{
int m;
int a, b;
cin >> m;
for(int i = 0; i <= 1024; ++i)
{
edge[i].to = 0;
edge[i].next = 0;
}
for(int i = 0; i < m; ++i)
{
cin >>a >> b;
add(a, b);
add(b, a);
Map[head[a]] = head[b];
Map[head[b]] = head[a];
++deg[a];
++deg[b];
}
int snode = 100000;
for(int i = 1; i < 501; ++i)
{
if(deg[i]&1)
snode = min(snode, i);
}
if(snode > 500)
snode = 1;
//cout <<snode<<endl;
Hierholzer(snode);
while(!ans.empty())
{
cout<<ans.top()<<endl;
ans.pop();
}
return 0;
}
/*
10
1 2
1 3
2 3
2 5
3 5
3 4
6 4
5 6
4 5
2 6
*/