poj 1041 John's trip(欧拉回路)

题意:给出一幅无向图,用每条边的编号及其两个端点编号描述,求无向图的欧拉回路,按字典序最小的边的编号输出;

思路:若存在度数为奇数的点,则欧拉回路不存在;dfs求欧拉回路;

#include<cstdio>
#include<cstring>
#include<algorithm>
#define maxn 2000
#define maxm 50
using namespace std;
struct node{
    int s,t;
}r[maxn];
bool vis[maxn];
int deg[maxm],s[maxn];//节点的度deg[],边序列s[]
int n,S,stop;      //边数n,节点的最小编号S,欧拉回路的边数stop
bool exist()     //若存在度数为奇数的节点,则返回0,不存在欧拉回路;
{
    for(int i=1;i<maxm;i++)
        if(deg[i]%2==1) return 0;
    return 1;
}
void dfs(int now)
{
    for(int i=1;i<=n;i++)
    if(!vis[i]&&(r[i].s==now||r[i].t==now)){//递归搜索与now相连的未访问的边
        vis[i]=1;
        dfs(r[i].s+r[i].t-now); //该边的另一端点
        s[++stop]=i;
    }
}
int main()
{
    int x,y,num;
    while(scanf("%d%d",&x,&y)){
        if(x<=0||y<=0) break;
        S=min(x,y);n=0;
        memset(deg,0,sizeof(deg));
        scanf("%d",&num);
        r[num].s=x;r[num].t=y;
        deg[x]++;deg[y]++;
        n=max(n,num);
        while(scanf("%d%d",&x,&y)){
            if(x<=0) break;
            S=min(x,y);
            scanf("%d",&num);
            r[num].s=x;r[num].t=y;
            deg[x]++;deg[y]++;
            n=max(n,num);
        }
        if(exist()){ //确保无度数为奇数的点
            stop=0;
            memset(vis,0,sizeof(vis));
            dfs(S);   //从最小节点出发,递归计算欧拉回路
            for(int i=stop;i>=2;i--) printf("%d ",s[i]);
            printf("%d\n",s[1]);
         }
         else
            printf("Round trip does not exist.\n");
    }
    return 0;
}

 

posted on 2015-05-31 12:31  大树置林  阅读(177)  评论(0编辑  收藏  举报

导航