无向图欧拉回路求法

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]);

    }

}


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