即一笔画问题。起点和终点相同称为回路,否则称为道路
欧拉回路或道路存在判定
无向图
联通,有0个或2个奇点(度为奇数)。
如果有两个奇点,则必须从一个奇点出发,另一个奇点终止。
如果奇点不存在,则可以从任意点出发,最终一定会回到该点。
有向图
最多只能有两个点的入度不等于出度,而且必须是其中一个点的出度恰好比入度大1(把它作为起点),另一个点的入度比出度大1(把它作为终点)。当然,还有一个前提条件:在忽略边的方向后,图必须是连通的。
程序
下面的程序同时适用于欧拉回路和道路。但如果需要打印欧拉道路,在主程序中调用时,参数必须是道路的起点。另外,打印的顺序是逆序的,因此需要队列替换printf
void euler(int u){
for (int v=0; v<n; v++) if (G[u][v] && !vis[u][v]) {
vis[u][v] = vis[v][u] = 1;
euler(v);
printf("%d %d\n", u, v);
}
}
尽管上面的代码只适用于无向图,但不难改成有向图;把vis[u][v] = vis[v][u] =1
改成vis[u][v]
即可。
小结
为何输出是逆序的?个人认为,将起点作为参数调用后,该dfs第一次调用printf必然是无路可走时,即是终点,因为其他点都是度为偶数的。
所以我认为该程序最终输出是从终点走到起点,然后起点出发继续DFS最终会回到起点。所以如果是有向图的话, 输出需做调整。