John's Trip

https://loj.ac/problem/10109

题目描述

  给出一张无向图和起点,求是否存在一条路径从起点出发访问完所有边并回到起点,若存在,输出路径。

思路

  如果一张图存在欧拉回路,那么显然从任意一点出发均可。所以我们判断完是否存在欧拉回路后,从起点开始dfs走,暴力尝试走完所有边,并把走过的点删去,最后看答案中是否有m条边即可,若无,则图不连通,这样可省略图连通性的判定。不过进行是否访问过时注意是否是已访问过的边的反向边。

代码

#include <bits/stdc++.h>
using namespace std;
const int N=50,M=4010;

int nxt[M],to[M],tot,head[N],num[M];
void add_edge(int x,int y,int z)
{
    nxt[++tot]=head[x];
    head[x]=tot;
    to[tot]=y;
    num[tot]=z;
}

int read()
{
    int res=0,w=1;
    char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-')w=-1;ch=getchar();}
    while(ch>='0'&&ch<='9'){res=(res<<3)+(res<<1)+ch-'0';ch=getchar();}
    return res*w;
}

int st[M],top;
vector<int> ans;
bool vis[M];
void dfs(int u)
{
    for(int &i=head[u];i;i=nxt[i])
    {
        int j=num[i];
        if(vis[j])continue ;
        vis[j]=1;
        dfs(to[i]);
        ans.push_back(j);
    }
}
int deg[M];
void clear()
{
    memset(head,0,sizeof(head));
    memset(vis,0,sizeof(vis));
    memset(deg,0,sizeof(deg));
    tot=0;top=0;ans.clear();
}

int main() 
{
//    freopen("a.in","r",stdin);
//    freopen("a.out","w",stdout);
    int x,y,z;
    while(1)
    {
        x=read();y=read();
        if(x==0&&y==0)break ;
        z=read();
        clear();
        int n=0,m=0,st=min(x,y);
        add_edge(x,y,z);add_edge(y,x,z);
        deg[x]++;deg[y]++;
        n=max(n,max(x,y));m=max(m,z);
        while(1)
        {
            x=read();y=read();
            if(x==0&&y==0)break ;
//            cout<<x<<' '<<y<<endl;
            z=read();
            add_edge(x,y,z);add_edge(y,x,z);
            deg[x]++;deg[y]++;
            n=max(n,max(x,y));m=max(m,z);
        }
        bool f=0;
        for(int i=1;i<=n;i++)
            if(deg[i]&1)
            {
                f=1;
                printf("Round trip does not exist.\n");
                break ;
            }
        if(f)continue ;
        dfs(st);
        if(ans.size()!=m)
        {
            printf("Round trip does not exist.\n");
            continue ;
        }
        for(int i=m-1;i>0;i--)
            printf("%d ",ans[i]);
        printf("%d\n",ans[0]);
    }
}

猜你喜欢

转载自www.cnblogs.com/fangbozhen/p/11748623.html