【歐拉回路】UOJ117[歐拉回路]題解

題目概述

判斷無向圖和有向圖是不是歐拉回路。如果是,求出任意一條歐拉回路。

解題報告

判斷歐拉回路:

  • 無向圖:每個點的度數都是偶數。
  • 有向圖:每個點的出度都等於入度。

證明?我不會啊!怎麼求歐拉回路呢?因爲已經確定了是歐拉回路,所以我們可以直接DFS瞎搞。隨便從一個點開始DFS,一條邊走過後就刪除。回溯時將其入隊。最後的隊列反過來就是答案。

原理:最後的隊列是返回路徑,所以反過來就是答案。證明?我不會啊!

示例程序

#include<cstdio>
#include<cctype>
#include<cstring>
using namespace std;
const int maxn=100000,maxm=400000;

int tp,n,m,fa[maxm+5],ans[maxm+5],f[maxn+5],g[maxn+5];
int E,lnk[maxn+5],son[maxm+5],nxt[maxm+5],w[maxm+5];bool vis[maxn+5];

#define Eoln(x) ((x)==10||(x)==13||(x)==EOF)
inline char readc(){
    static char buf[100000],*l=buf,*r=buf;
    if (l==r) r=(l=buf)+fread(buf,1,100000,stdin);
    if (l==r) return EOF;return *l++;
}
inline int readi(int &x){
    int tot=0,f=1;char ch=readc(),lst='+';
    while (!isdigit(ch)) {if (ch==EOF) return EOF;lst=ch;ch=readc();}
    if (lst=='-') f=-f;
    while (isdigit(ch)) tot=(tot<<3)+(tot<<1)+ch-48,ch=readc();
    return x=tot*f,Eoln(ch);
}
#define Add(x,y,z) son[E]=(y),w[E]=(z),fa[E]=E,nxt[E]=lnk[x],lnk[x]=E++,f[y]++,g[x]++
#define Del(j) fa[j]=getfa(nxt[j])
int getfa(int x) {if (x<0||fa[x]==x) return x;return fa[x]=getfa(fa[x]);}
void Dfs(int x){
    vis[x]=true;
    for (int j=getfa(lnk[x]);~j;j=getfa(nxt[j])){
        Del(j);if (tp==1) Del(j^1);
        Dfs(son[j]);ans[++ans[0]]=w[j];
    }
}
int main(){
    freopen("program.in","r",stdin);
    freopen("program.out","w",stdout);
    readi(tp);readi(n);readi(m);memset(lnk,255,sizeof(lnk));
    for (int i=1,x,y;i<=m;i++) {readi(x);readi(y);Add(x,y,i);if (tp==1) Add(y,x,-i);}
    if (tp==1) {for (int i=1;i<=n;i++) if (f[i]&1) return puts("NO"),0;}
    else for (int i=1;i<=n;i++) if (f[i]!=g[i]) return puts("NO"),0;
    Dfs(son[0]);for (int i=1;i<=n;i++) if ((f[i]||g[i])&&!vis[i]) return puts("NO"),0;
    puts("YES");while (ans[0]) printf("%d ",ans[ans[0]--]);
    return 0;
}
\
發佈了340 篇原創文章 · 獲贊 124 · 訪問量 18萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章