欧拉图及欧拉路浅谈


1.【定义】

欧拉路我们将其称为是一个图中从某一节点 \(S\) 出发,恰好经过图中每条边各一次,但是可以重复经过图中节点的路。

欧拉回路就是指就是从某点 \(S\) 出发最后仍回到 \(S\) 的欧拉路。

存在欧拉路的图被称为欧拉图。

存在欧拉路但是不存在欧拉回路的图叫做半欧拉图。

2.【判定】

【欧拉图的判定】

一张无向图为欧拉图,仅当无向图连通,并且每个节点的度数为偶数。

证明: 等价于判定是否存在欧拉回路,而每条边都要经过,然后回到最开始等价于是进行出去与回来的反复操作,所以判定正确。

【欧拉路存在性判定】

一张无向图中存在欧拉路,仅当无向图连通,并且恰好只有两个节点 \(S\)\(T\) 的度数为奇数其他均为偶数。

证明: 等价于是不在回到起点的欧拉回路,联合上面证明所以显然。

【半欧拉图的判定】

一张无向图是半欧拉图当且仅当这个图是连通的,并且恰好有 \(2\) 个奇度数节点。

证明: 等价于判断处在欧拉路。

【有向图欧拉图判定】

所有点属于一个强连通分量且每个顶点的入度和出度相同。

【有向图半欧拉图判定】

将所有有向边变成无向边时,所有点属于一个强连通分量。

最多只有一个顶点的出度与入度差为 \(1\)

最多只有一个顶点的入度与出度差为 \(1\)

所有其他顶点的入度与出度相同。

3.【题目】

P7771 【模板】欧拉路径

求有向图字典序最小的欧拉路径。


模板欧拉路,按照上面的方法模拟就是了。


const int N = 3e5;
int n, m, in[N], out[N], vis[N], ans[N], num, cur[N];
vector<int> ver[N];
void dfs(int x) {
  for (int i = cur[x]; i < ver[x].size(); i = cur[x]) {
    cur[x] = i + 1;
    dfs(ver[x][i]);
  }
  ans[++num] = x;
}
signed main() {
  n = read(), m = read();
  for (int i = 1; i <= m; i++) {
    int a = read(), b = read();
    ver[a].push_back(b);
    in[b]++;
    out[a]++;
  }
  for (int i = 1; i <= n; i++)
    sort(ver[i].begin(), ver[i].end());
  int pd = 0, st = 1, en = 0;
  for (int i = 1; i <= n; i++) {
    if (in[i] == out[i])
      continue;
    else {
      if (in[i] + 1 == out[i]) {
        if (pd && st) {
          printf("No\n");
          return 0;
        } else
          st = i;
      }
      if (out[i] + 1 == in[i]) {
        if (en) {
          printf("No\n");
          return 0;
        } else
          en = i;
      }
      pd = 1;
    }
  }
  dfs(st);
  for (int i = num; i; i--)
    printf("%lld ", ans[i]);
  printf("\n");
  return 0;
}


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM