分析
对于无向图中边的编号t的说明:
C++ 代码
#include<bits/stdc++.h>
using namespace std;
const int N = 1e5+10,M = 4e5+10;
int n,m,ans[M / 2],cnt,type;;
int h[N],e[M],ne[M],idx;
int din[N],dout[N];
bool used[M];
void add(int a,int b)
{
e[idx]=b,ne[idx]=h[a],h[a]=idx++;
}
void dfs(int u)
{
for(int &i=h[u];~i;)
{
if(used[i])
{
i=ne[i]; //删除这条边
continue;
}
used[i]=true;
if(type==1) used[i^1]=true;
int t;
if(type==1) //无向图时,正边是t=i/2+1,反边是-t
{
t=i/2+1;
if(i&1) t=-t;
}
else t=i+1;
int j=e[i];
i=ne[i]; //删除这条边
dfs(j);
ans[++cnt]=t; //该边加入欧拉回路
}
}
int main()
{
memset(h,-1,sizeof h);
scanf("%d",&type);
scanf("%d%d",&n,&m);
int a,b;
for(int i=0;i<m;i++)
{
scanf("%d%d",&a,&b);
add(a,b);
if(type==1) add(b,a); //无向边要加上反边
dout[a]++,din[b]++;
}
if(type==1) //无向图欧拉回路要求每个点的度数(入度+出度)不能为奇数
{
for(int i=1;i<=n;i++)
{
if((din[i]+dout[i])%2)
{
puts("NO");
return 0;
}
}
}
else{ //有向图要求每个点度数的出度等于入度
for(int i=1;i<=n;i++)
{
if(din[i]!=dout[i])
{
puts("NO");
return 0;
}
}
}
for(int i=1;i<=n;i++) //从第一个有边连接的点开始进行走欧拉回路的流程
{
if(h[i]!=-1)
{
dfs(i);
break;
}
}
if(cnt<m) //如果最后遍历到边的数量小于m,说明图不是连通图,直接输出NO
{
puts("NO");
return 0;
}
puts("YES");
for(int i=cnt;i;i--) //输出欧拉回路
printf("%d ",ans[i]);
return 0;
}