歐拉圖及歐拉路淺談


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