無向圖歐拉回路求法

poj 1041



這個題比較難,然後我也不懂,看了看別人的題解,算是懂了點,但仍然感覺思路不是很清楚


看看http://www.cnblogs.com/ylfdrib/archive/2010/08/24/1807602.html

這個講的比較好


這道題很不錯,由於圖已經保證連通,首先用度數是否是偶數,判斷圖是否是歐拉圖,然後,輸出最小升序,就成了一大難題,百科上有代碼,這題讓我理解了深搜的又一強大功能,其實就是每次都從小往大的搜,先搜得一個最小序環,然後對環上的每一點進行搜索,其實對於歐拉圖而言,每個點要麼就只剩一個點,什麼也搜不到了,要麼還有一個環,只要把環上路徑全都插入到對應位置上,用棧存路徑,每次只有回溯到當前點,就是說當前點的後繼都已經搜過了的時候,才把當前點入棧,這樣一來倒着輸出,就能得到一個歐拉回路,而且是最小升序。


就是這樣一個代碼,就能實現歐拉回路的輸出,唯一一點特別的就是,stk[++top] = e,是在v點搜完了才執行的,想想就知道這有什麼含義,這樣纔是真正的最小序歐拉回路。實現代碼見下:




#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<string>
#include<algorithm>
using namespace std;
const int maxn = 1000 + 10 ;
int Map[maxn][maxn];//Map[u][z]=v,表示u通過邊Z與v相連
int adj[maxn][maxn];//adj[u][i]=z,表示u的第i條邊爲z
int vis[maxn];
int num[maxn];
int st[maxn];// ji lu lu jing
int idx,S,top;
int cmp(const void *a,const void *b){
    return *(int *)a-*(int *)b;
}
void dfs(int u){
    int i,v,e;
    for(int i=1;i<=num[u];i++){

       e=adj[u][i];
       if(!vis[e]){
        v=Map[u][e];
        vis[e]=1;
        dfs(v);
        st[++top]=e;
       }
    }

}
void ori(){
    memset(vis,0,sizeof(vis));
    memset(num,0,sizeof(num));
    memset(Map,0,sizeof(Map));
    memset(st,0,sizeof(st));
    top=0;
}
int main(){
    int a,b,z;
    while(~scanf("%d%d",&a,&b)){

        if(a==0&&b==0)break;
        ori();
        S=min(a,b);
        scanf("%d",&z);
        adj[a][++num[a]]=z;
        adj[b][++num[b]]=z;
        Map[a][z]=b;
        Map[b][z]=a;
        while(scanf("%d%d", &a, &b) != EOF){
          if (a == 0 && b == 0) break;
          scanf("%d", &z);
          adj[a][++num[a]] = z;
          adj[b][++num[b]] = z;
          Map[a][z] = b;
          Map[b][z] = a;
        }
       int i;
       for(i=1;;i++){
        if(num[i]==0)break;
        if(num[i]%2)break;
       }
       if(num[i]!=0){printf("Round trip does not exist.\n");continue;}
       int maxN=i-1;
       for(i=1;i<=maxN;i++){
        qsort(adj[i]+1,num[i],sizeof(int),cmp);
       }
       dfs(S);
       for(int i=top;i>1;i--)printf("%d ",st[i]);
       printf("%d\n",st[1]);

    }

}


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