模板 - 歐拉路、歐拉回路(一筆畫問題)

ACM-ICPC模板


歐拉回路就是給一個圖,存在一條迴路把所邊經過且每條邊只經過一次。“一筆畫問題

對於無向圖:

存在歐拉回路的條件:每個點的度都爲偶數;
  
存在歐拉路的條件:有且只有兩個點的度爲一,且這兩個點分別爲起點和終點;

對於有向圖:

存在歐拉回路的條件:每個點出度等於入度;

存在歐拉路的條件:存在一個點出度比入度多一作爲起點,存在一點入度比出度多一作爲終點,其餘點出度等於入度;

求歐拉回路

解決問題:給定一張無向圖,求出它的歐拉回路,若不止一條,隨意輸出一條即可

const int N = 5e4+7;
const int M = 5e5+7;
int head[N],nex[M],ver[M],tot = 1;
bool vis[M];
int stk[M],ans[M];//模擬系統棧、答案棧
int n,m,s,t,cnt,top;
queue<int>q;

void add(int x,int y){
    ver[++tot] = y;nex[tot] = head[x];head[x] = tot;
}

void euler(){//模擬dfs遞歸
    stk[++top] = 1;//起點
    while(top > 0){
        int x = stk[top],i = head[x];
        while(i && vis[i])i = nex[i];//找到一條尚未訪問過的路
        // 與x相連的所有邊均已訪問,模擬回溯過程,並記錄
        if(i){
            stk[++top] = ver[i];
            vis[i] = ver[i ^ 1] = true;//正常的歐拉回路模板
            head[x] = nex[i];
        }
        else {// 與x相連的所有邊均已訪問,模擬回溯過程,並記錄
            top--;
            ans[++cnt] = x;
        }

    }
}

int main(){
    scanf("%d%d",&n,&m);
    tot = 1;
    over(i,1,m){
        int x,y;
        scanf("%d%d",&x,&y);
        add(x,y);add(y,x);
    }
    euler();
    over(i,1,cnt)
    printf("%d\n",ans[i]);
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章