题目链接
好极了的欧拉回路,我们想知道怎样才能跑完所有的边,我们可以从度为奇数的点出发——因为这是欧拉回路的无向图的先觉调节,当然,这道题还有另外一种可能就是这是一个环,1->2, 2->3, 3->4, 4->1,那么就没有奇数度的点了,就是随便找一个id最小的点出发就是了。
接下来讲解一下欧拉回路在本题中的思考,本题有坑点,但是放在后头说,我们首先得判断这群点是否在一棵树上,不然的话就跑不到所有的边,既然所有的边都要跑到,在存在奇数度的点的情况的时候,我们断不能从偶数度的点出发,先找到个id最小的奇数点,并从它出发,知道最终找到结束的节点,并且,结束的那个节点也断然是个奇数度的节点;另外,不存在奇数度的点情况呢,就是它们是一个完整的环,对于这样的情况,我们直接找到个最小id序的有度节点即可,当然强调有度的节点,不然会WA,因为题意没说节点从1开始(WA了好几发的亲身经历)。
#include <iostream>
#include <cstdio>
#include <cmath>
#include <string>
#include <cstring>
#include <algorithm>
#include <limits>
#include <vector>
#include <stack>
#include <queue>
#include <set>
#include <map>
#define lowbit(x) ( x&(-x) )
#define pi 3.141592653589793
#define e 2.718281828459045
using namespace std;
typedef unsigned long long ull;
typedef long long ll;
const int maxN = 505;
int N, M, du[maxN]={0}, path[maxN][maxN]={0}, root[maxN], rx, ry, st, ed, out_put[maxN], keys;
vector<int> vt[maxN];
struct Eddge
{
int no, to;
Eddge(int a=0, int b=0):no(a), to(b) {}
}edge[maxN<<1];
int fid(int x) { return x==root[x]?x:(root[x] = fid(root[x])); }
void init()
{
for(int i=1; i<=N; i++) root[i] = i;
}
void dfs(int u)
{
int len = (int)vt[u].size();
for(int i=0; i<len; i++)
{
int v = vt[u][i];
if(path[u][v])
{
path[u][v]--;
path[v][u]--;
dfs(v);
out_put[++keys] = u;
}
}
}
int main()
{
scanf("%d%d", &N, &M);
init();
for(int i=1; i<=M; i++)
{
scanf("%d%d", &edge[i].no, &edge[i].to);
path[edge[i].no][edge[i].to]++;
path[edge[i].to][edge[i].no]++;
vt[edge[i].to].push_back(edge[i].no);
vt[edge[i].no].push_back(edge[i].to);
du[edge[i].no]++;
du[edge[i].to]++;
rx = fid(edge[i].no); ry = fid(edge[i].to);
if(rx != ry) root[rx] = ry;
}
for(int i=1; i<=N; i++) sort(vt[i].begin(), vt[i].end());
int num = 0, the_tree = 0;
for(int i=1; i<=N; i++)
{
if(du[i] & 1) num++;
if(root[i] == i && du[i]) the_tree++;
}
if(num > 2 || the_tree>1) { printf("-1\n"); return 0; }
st = ed = 1;
for(int i=1; i<=N; i++)
{
if(du[i]) { st = ed = i; break; } //题中没说节点从1开始
}
if(num == 2)
{
for(int i=1; i<=N; i++)
{
if(du[i] & 1)
{
st = ed = i;
break;
}
}
for(int i=N; i>=1; i--)
{
if(du[i] & 1)
{
ed = i;
break;
}
}
}
dfs(st);
for(int i=keys; i>=1; i--) printf("%d ", out_put[i]);
printf("%d\n", ed);
return 0;
}