1. 程式人生 > >有向圖歐拉回路

有向圖歐拉回路

Watchcow
Time Limit: 3000MS Memory Limit: 65536K
Total Submissions: 5902 Accepted: 2538 Special Judge

Description

Bessie's been appointed the new watch-cow for the farm. Every night, it's her job to walk across the farm and make sure that no evildoers are doing any evil. She begins at the barn, makes her patrol, and then returns to the barn when she's done. 

If she were a more observant cow, she might be able to just walk each of M (1 <= M <= 50,000) bidirectional trails numbered 1..M between N (2 <= N <= 10,000) fields numbered 1..N on the farm once and be confident that she's seen everything she needs to see. But since she isn't, she wants to make sure she walks down each trail exactly twice. It's also important that her two trips along each trail be in opposite directions, so that she doesn't miss the same thing twice. 

A pair of fields might be connected by more than one trail. Find a path that Bessie can follow which will meet her requirements. Such a path is guaranteed to exist.

Input

* Line 1: Two integers, N and M. 

* Lines 2..M+1: Two integers denoting a pair of fields connected by a path.

Output

* Lines 1..2M+1: A list of fields she passes through, one per line, beginning and ending with the barn at field 1. If more than one solution is possible, output any solution.

Sample Input

4 5
1 2
1 4
2 3
2 4
3 4

Sample Output

1
2
3
4
2
1
4
3
2
4
1
分析:

其實我們不能死瞄著dfs一直深搜,這樣就很難想通了,我們可以想想,尤拉圖的節點的度的問題,(我這裡就專門討論有向圖,無向圖可以轉換成有向圖做的),假設節點s為起點,則深搜到不能搜的時候那個節點就是s。為什麼呢,只要將這點想通,基本就沒什麼問題了。

我們知道如果一個節點入度減1,那麼它的出度必然要減1,在以s為起點的路徑中,se1v1e2v2....eivi,如果vi節點

不是s節點且為深搜的最後節點,也就是說vi沒有了出度,然而我們知道對於v1...v(i-1)節點入度一但減少,出度也就減少了,然而對於s起點來說只要出度減少卻沒有入度減少,vi的入度減少卻沒有了出度,所以證明vi節點不可能會成為不是s節點且為深搜的最後節點,即除非他還不是深搜的最後節點,到這裡我們基本就可以確定了,vi要滿足深搜最後節點必然為vi==s,這樣的話vi的入度減少了,出度也減少了(因為s出度減少了),s的出度減少了,入度也減少了(因為vi的入度減少了)所以可以證明以s為起點的深搜最後節點也為s。

哎呀,說的有點累了,不知道大家明白沒。

然後就是返回了,當沿著路徑返回的途中如果vi節點還有出度的話,那麼就以vi為起點開始深搜,根據上面的證明,我們可以知道最後的深搜節點肯定為vi起點了。

現在大概知道我要最後說什麼了吧,將回路se1v1e2v2.....eivi(ei1vi1ei2vi2...eiivi)e(i+1).....ejs,括號裡面的就是返回途中發生的又一次迴路咯,把它嵌入到裡面自然大的迴路也滿足要求了。

#include"stdio.h"
#include"string.h"
#include"queue"
#include"stack"
#include"iostream"
#include"string"
#include"map"
#include"stdlib.h"
#define inf 99999999
#define M 10009
using namespace std;
struct node
{
    int u,v,next;
}edge[M*15];
int t,head[M],use[M*15],s[M*15],cnt,Stack[M*15],m;
void init()
{
    t=0;
    memset(head,-1,sizeof(head));
}
void add(int u,int v)
{
    edge[t].u=u;
    edge[t].v=v;
    edge[t].next=head[u];
    head[u]=t++;
}
void DFS(int u)
{
    for(int i=head[u];i!=-1;i=edge[i].next)
    {
        int v=edge[i].v;
        if(!use[i])
        {
            use[i]=1;
            DFS(v);
        }
    }
    printf("%d\n",u);
}
int main()
{
    int n,i;
    while(scanf("%d%d",&n,&m)!=-1)
    {
        init();
        for(i=1;i<=m;i++)
        {
            int a,b;
            scanf("%d%d",&a,&b);
            add(a,b);
            add(b,a);
        }
        memset(use,0,sizeof(use));
        DFS(1);
    }
}