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