无向图存在欧拉的充分必要条件: 当且仅当存在2个或者0个度数为奇数的点 并且 所有边连通
无向图为欧拉图的充要条件: 当且仅当图中所有点的度数为偶数 并且 所有边连通
有向图存在欧拉路径的充要条件: 当且仅当除了两个点或者0个点外其他所有点的初度等于入度,剩下的两个点一个出度比入度多一,另一个点入度比出度多一 并且 所有边连通
有向图为欧拉图的充要条件: 所有点的初度和入度相等 并且 所有边连通
怎样寻找欧拉回路或者欧拉路径。
上述中一个点可能会被多次遍历,每次都会扫描与它相邻的所有边, 最坏的情况下,只有一个点m条边,那么每次都会遍历这个点都会遍历m次边因此O(M^2)的。
优化:用邻接表存储,没遍历一条边就把他删去,时间复杂度降到O(N+M)。
怎么做?
void dfs(int u)
{
for(int &i = h[u] ; ~i;) // 用引用直接吧i指向h[u]的地址,每次改变i就等价与改变h[u], 每次改变h[u]也相当于改变i;
{
int j = e[i];
if(used[i])//对于每一条边如果没有被用过我们就立即用它并把它删去,如果用过了它,那么我们就应该把它删去跳过它
{
i = ne[i];
continue;
}
used[i] = true;
i = ne[i];
int t = i / 2 + 1; // 对于无向图的边的编号
int t = i + 1; // 对于有向图的边的编号
dfs(j);
ans[++ cnt] = t; //把边加入到栈中
}
}
如果题目要求输出最小字典序的欧拉路径的点号怎么做?
只需要按照从小到大的顺序遍历每个可以再次到达的点即可。